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 appImManager from "../../lib/appManagers/appImManager";
|
||||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||||
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||||
|
import appSidebarRight from "../../lib/appManagers/appSidebarRight";
|
||||||
import { findUpClassName, $rootScope } from "../../lib/utils";
|
import { findUpClassName, $rootScope } from "../../lib/utils";
|
||||||
import appForward from "../appForward";
|
|
||||||
import { parseMenuButtonsTo, attachContextMenuListener, positionMenu, openBtnMenu } from "../misc";
|
import { parseMenuButtonsTo, attachContextMenuListener, positionMenu, openBtnMenu } from "../misc";
|
||||||
import { PopupButton, PopupPeer } from "../popup";
|
import { PopupButton, PopupPeer } from "../popup";
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ export class ChatContextMenu {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.buttons.forward.addEventListener('click', () => {
|
this.buttons.forward.addEventListener('click', () => {
|
||||||
appForward.init([this.msgID]);
|
appSidebarRight.forwardTab.open([this.msgID]);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.buttons.edit.addEventListener('click', () => {
|
this.buttons.edit.addEventListener('click', () => {
|
||||||
|
@ -1,25 +1,11 @@
|
|||||||
import { findUpTag, whichChild } from "../lib/utils";
|
import { findUpTag, whichChild } from "../lib/utils";
|
||||||
|
|
||||||
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {
|
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
|
||||||
/* if(toRight) {
|
const elements = [tabContent, prevTabContent];
|
||||||
//prevTabContent.style.filter = `brightness(80%)`;
|
if(toRight) elements.reverse();
|
||||||
prevTabContent.style.transform = `translateX(-25%)`;
|
elements[0].style.filter = `brightness(80%)`;
|
||||||
tabContent.style.transform = `translateX(20%)`;
|
elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;
|
||||||
} else {
|
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
||||||
//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)`;
|
|
||||||
}
|
|
||||||
|
|
||||||
tabContent.classList.add('active');
|
tabContent.classList.add('active');
|
||||||
void tabContent.offsetWidth; // reflow
|
void tabContent.offsetWidth; // reflow
|
||||||
@ -28,15 +14,11 @@ function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, t
|
|||||||
tabContent.style.filter = '';
|
tabContent.style.filter = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {
|
function slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
|
||||||
const width = prevTabContent.getBoundingClientRect().width;
|
const elements = [tabContent, prevTabContent];
|
||||||
if(toRight) {
|
if(toRight) elements.reverse();
|
||||||
tabContent.style.transform = `translate3d(${width}px, 0, 0)`;
|
elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;
|
||||||
prevTabContent.style.transform = `translate3d(${-width}px, 0, 0)`;
|
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
||||||
} else {
|
|
||||||
tabContent.style.transform = `translate3d(${-width}px, 0, 0)`;
|
|
||||||
prevTabContent.style.transform = `translate3d(${width}px, 0, 0)`;
|
|
||||||
}
|
|
||||||
|
|
||||||
tabContent.classList.add('active');
|
tabContent.classList.add('active');
|
||||||
void tabContent.offsetWidth; // reflow
|
void tabContent.offsetWidth; // reflow
|
||||||
@ -72,11 +54,15 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?
|
|||||||
}
|
}
|
||||||
|
|
||||||
const toRight = prevId < id;
|
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') {
|
if(tabs || content.dataset.slider == 'tabs') {
|
||||||
slideTabs(tabContent, prevTabContent, toRight);
|
slideTabs(tabContent, prevTabContent, width, toRight);
|
||||||
} else {
|
} else {
|
||||||
slideNavigation(tabContent, prevTabContent, toRight);
|
slideNavigation(tabContent, prevTabContent, width, toRight);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tabContent.classList.add('active');
|
tabContent.classList.add('active');
|
||||||
|
@ -1,20 +1,32 @@
|
|||||||
import appSidebarRight from "../lib/appManagers/appSidebarRight";
|
import appSidebarRight, { AppSidebarRight } from "../../lib/appManagers/appSidebarRight";
|
||||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||||
import { putPreloader } from "./misc";
|
import { putPreloader } from "../misc";
|
||||||
import { AppSelectPeers } from "./appSelectPeers";
|
import { AppSelectPeers } from "../appSelectPeers";
|
||||||
|
import { SliderTab } from "../slider";
|
||||||
|
|
||||||
class AppForward {
|
export default class AppForwardTab implements SliderTab {
|
||||||
public container = document.getElementById('forward-container') as HTMLDivElement;
|
public container: HTMLElement;
|
||||||
private closeBtn = this.container.querySelector('.sidebar-close-button') as HTMLButtonElement;
|
public closeBtn: HTMLElement;
|
||||||
private sendBtn = this.container.querySelector('.btn-circle') as HTMLButtonElement;
|
private sendBtn: HTMLButtonElement;
|
||||||
|
|
||||||
private selector: AppSelectPeers;
|
private selector: AppSelectPeers;
|
||||||
private msgIDs: number[] = [];
|
private msgIDs: number[] = [];
|
||||||
|
|
||||||
private sidebarWasActive: boolean;
|
onCloseAfterTimeout() {
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
public cleanup() {
|
||||||
this.closeBtn.addEventListener('click', this.close.bind(this));
|
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', () => {
|
this.sendBtn.addEventListener('click', () => {
|
||||||
let peerIDs = this.selector.getSelected();
|
let peerIDs = this.selector.getSelected();
|
||||||
@ -44,25 +56,15 @@ class AppForward {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public open(ids: number[]) {
|
||||||
(this.sidebarWasActive ? Promise.resolve() : appSidebarRight.toggleSidebar(false)).then(() => {
|
if(this.init) {
|
||||||
this.cleanup();
|
this.init();
|
||||||
this.container.classList.remove('active');
|
this.init = null;
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public cleanup() {
|
|
||||||
if(this.selector) {
|
|
||||||
this.selector.container.remove();
|
|
||||||
this.selector = null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public init(ids: number[]) {
|
|
||||||
this.cleanup();
|
this.cleanup();
|
||||||
this.msgIDs = ids;
|
this.msgIDs = ids;
|
||||||
|
|
||||||
this.container.classList.add('active');
|
|
||||||
this.sendBtn.innerHTML = '';
|
this.sendBtn.innerHTML = '';
|
||||||
this.sendBtn.classList.add('tgico-send');
|
this.sendBtn.classList.add('tgico-send');
|
||||||
this.sendBtn.disabled = false;
|
this.sendBtn.disabled = false;
|
||||||
@ -75,10 +77,8 @@ class AppForward {
|
|||||||
}
|
}
|
||||||
}, ['dialogs', 'contacts'], () => {
|
}, ['dialogs', 'contacts'], () => {
|
||||||
//console.log('forward rendered:', this.container.querySelector('.selector ul').childElementCount);
|
//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);
|
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
|
onCloseAfterTimeout?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const TRANSITIONTIME = 250;
|
const TRANSITION_TIME = 250;
|
||||||
|
|
||||||
export default class SidebarSlider {
|
export default class SidebarSlider {
|
||||||
protected _selectTab: (id: number) => void;
|
protected _selectTab: (id: number) => void;
|
||||||
public historyTabIDs: number[] = [];
|
public historyTabIDs: number[] = [];
|
||||||
|
|
||||||
constructor(public sidebarEl: HTMLElement, public tabs: {[id: number]: SliderTab}) {
|
constructor(public sidebarEl: HTMLElement, public tabs: {[id: number]: SliderTab}, canHideFirst = false) {
|
||||||
this._selectTab = horizontalMenu(null, this.sidebarEl.querySelector('.sidebar-slider') as HTMLDivElement, null, null, TRANSITIONTIME);
|
this._selectTab = horizontalMenu(null, this.sidebarEl.querySelector('.sidebar-slider') as HTMLDivElement, null, null, TRANSITION_TIME);
|
||||||
this._selectTab(0);
|
if(!canHideFirst) {
|
||||||
|
this._selectTab(0);
|
||||||
|
}
|
||||||
|
|
||||||
let onCloseBtnClick = () => {
|
let onCloseBtnClick = () => {
|
||||||
//console.log('sidebar-close-button click:', this.historyTabIDs);
|
//console.log('sidebar-close-button click:', this.historyTabIDs);
|
||||||
let closingID = this.historyTabIDs.pop(); // pop current
|
let closingID = this.historyTabIDs.pop(); // pop current
|
||||||
this.onCloseTab(closingID);
|
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 => {
|
Array.from(this.sidebarEl.querySelectorAll('.sidebar-close-button') as any as HTMLElement[]).forEach(el => {
|
||||||
el.addEventListener('click', onCloseBtnClick);
|
el.addEventListener('click', onCloseBtnClick);
|
||||||
@ -30,7 +32,7 @@ export default class SidebarSlider {
|
|||||||
|
|
||||||
public selectTab(id: number) {
|
public selectTab(id: number) {
|
||||||
if(this.historyTabIDs[this.historyTabIDs.length - 1] == id) {
|
if(this.historyTabIDs[this.historyTabIDs.length - 1] == id) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tab = this.tabs[id];
|
const tab = this.tabs[id];
|
||||||
@ -42,13 +44,13 @@ export default class SidebarSlider {
|
|||||||
if(tab.onOpenAfterTimeout) {
|
if(tab.onOpenAfterTimeout) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tab.onOpenAfterTimeout();
|
tab.onOpenAfterTimeout();
|
||||||
}, TRANSITIONTIME);
|
}, TRANSITION_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.historyTabIDs.push(id);
|
this.historyTabIDs.push(id);
|
||||||
this._selectTab(id);
|
this._selectTab(id);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeTabFromHistory(id: number) {
|
public removeTabFromHistory(id: number) {
|
||||||
@ -66,7 +68,7 @@ export default class SidebarSlider {
|
|||||||
if(tab.onCloseAfterTimeout) {
|
if(tab.onCloseAfterTimeout) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tab.onCloseAfterTimeout();
|
tab.onCloseAfterTimeout();
|
||||||
}, TRANSITIONTIME);
|
}, TRANSITION_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,14 +588,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="sidebar sidebar-right main-column" id="column-right">
|
<div class="sidebar sidebar-right main-column" id="column-right">
|
||||||
<div class="sidebar-content sidebar-slider tabs-container">
|
<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">
|
<div class="sidebar-header">
|
||||||
<button class="btn-icon tgico sidebar-close-button"></button>
|
<button class="btn-icon tgico sidebar-close-button"></button>
|
||||||
<div class="sidebar-header__title">Info</div>
|
<div class="sidebar-header__title">Info</div>
|
||||||
|
|
||||||
<!-- <button class="btn-icon rp tgico-edit sidebar-edit-button"></button> -->
|
<!-- <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-icon tgico-more rp btn-menu-toggle">
|
||||||
<div class="btn-menu bottom-left"> -->
|
<div class="btn-menu bottom-left"> -->
|
||||||
<!-- <div class="btn-menu-item menu-mute rp">Mute</div>
|
<!-- <div class="btn-menu-item menu-mute rp">Mute</div>
|
||||||
@ -649,20 +649,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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">
|
<div class="sidebar-header">
|
||||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="chats-container"></div>
|
<div class="chats-container"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-slider-item sidebar-search" id="forward-container">
|
<div class="sidebar-slider-item" id="forward-container">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||||
<div class="sidebar-header__title">Forward</div>
|
<div class="sidebar-header__title">Forward</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-primary btn-circle btn-icon rp btn-corner tgico-send"></button>
|
<button class="btn-primary btn-circle btn-icon rp btn-corner tgico-send"></button>
|
||||||
</div>
|
</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">
|
<div class="sidebar-header">
|
||||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||||
</div>
|
</div>
|
||||||
@ -675,7 +675,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="sidebar-content"><div class="poll-results"></div></div>
|
<div class="sidebar-content"><div class="poll-results"></div></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">
|
<div class="sidebar-header">
|
||||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,7 +8,7 @@ import appProfileManager from "./appProfileManager";
|
|||||||
import appDialogsManager from "./appDialogsManager";
|
import appDialogsManager from "./appDialogsManager";
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import appPhotosManager from "./appPhotosManager";
|
import appPhotosManager from "./appPhotosManager";
|
||||||
import appSidebarRight from './appSidebarRight';
|
import appSidebarRight, { AppSidebarRight } from './appSidebarRight';
|
||||||
|
|
||||||
import { logger, LogLevels } from "../logger";
|
import { logger, LogLevels } from "../logger";
|
||||||
import appMediaViewer from "./appMediaViewer";
|
import appMediaViewer from "./appMediaViewer";
|
||||||
@ -23,7 +23,6 @@ import Scrollable from '../../components/scrollable_new';
|
|||||||
import BubbleGroups from '../../components/bubbleGroups';
|
import BubbleGroups from '../../components/bubbleGroups';
|
||||||
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
||||||
import appDocsManager from './appDocsManager';
|
import appDocsManager from './appDocsManager';
|
||||||
import appForward from '../../components/appForward';
|
|
||||||
import appStickersManager from './appStickersManager';
|
import appStickersManager from './appStickersManager';
|
||||||
import AvatarElement from '../../components/avatar';
|
import AvatarElement from '../../components/avatar';
|
||||||
import appInlineBotsManager from './AppInlineBotsManager';
|
import appInlineBotsManager from './AppInlineBotsManager';
|
||||||
@ -511,7 +510,7 @@ export class AppImManager {
|
|||||||
return;
|
return;
|
||||||
} else if(target.classList.contains('forward')) {
|
} else if(target.classList.contains('forward')) {
|
||||||
const mid = +bubble.dataset.mid;
|
const mid = +bubble.dataset.mid;
|
||||||
appForward.init([mid]);
|
appSidebarRight.forwardTab.open([mid]);
|
||||||
return;
|
return;
|
||||||
} else if(target.classList.contains('name')) {
|
} else if(target.classList.contains('name')) {
|
||||||
let peerID = +target.dataset.peerID;
|
let peerID = +target.dataset.peerID;
|
||||||
@ -560,7 +559,7 @@ export class AppImManager {
|
|||||||
this.searchBtn.addEventListener('click', (e) => {
|
this.searchBtn.addEventListener('click', (e) => {
|
||||||
cancelEvent(e);
|
cancelEvent(e);
|
||||||
if(this.peerID) {
|
if(this.peerID) {
|
||||||
appSidebarRight.beginSearch();
|
appSidebarRight.searchTab.open(this.peerID);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -610,8 +609,8 @@ export class AppImManager {
|
|||||||
if(e.key == 'Escape') {
|
if(e.key == 'Escape') {
|
||||||
if(appMediaViewer.wholeDiv.classList.contains('active')) {
|
if(appMediaViewer.wholeDiv.classList.contains('active')) {
|
||||||
appMediaViewer.buttons.close.click();
|
appMediaViewer.buttons.close.click();
|
||||||
} else if(appForward.container.classList.contains('active')) {
|
} else if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) {
|
||||||
appForward.close();
|
appSidebarRight.forwardTab.closeBtn.click();
|
||||||
} else if(this.chatInputC.replyElements.container.classList.contains('active')) {
|
} else if(this.chatInputC.replyElements.container.classList.contains('active')) {
|
||||||
this.chatInputC.replyElements.cancelBtn.click();
|
this.chatInputC.replyElements.cancelBtn.click();
|
||||||
} else if(this.peerID != 0) { // hide current dialog
|
} else if(this.peerID != 0) { // hide current dialog
|
||||||
@ -885,16 +884,18 @@ export class AppImManager {
|
|||||||
public setPeerStatus(needClear = false) {
|
public setPeerStatus(needClear = false) {
|
||||||
if(!this.myID) return;
|
if(!this.myID) return;
|
||||||
|
|
||||||
|
const profileElements = appSidebarRight.sharedMediaTab.profileElements;
|
||||||
|
|
||||||
if(this.peerID < 0) { // not human
|
if(this.peerID < 0) { // not human
|
||||||
let chat = appPeersManager.getPeer(this.peerID);
|
let chat = appPeersManager.getPeer(this.peerID);
|
||||||
let isChannel = appPeersManager.isChannel(this.peerID) && !appPeersManager.isMegagroup(this.peerID);
|
let isChannel = appPeersManager.isChannel(this.peerID) && !appPeersManager.isMegagroup(this.peerID);
|
||||||
|
|
||||||
this.subtitleEl.classList.remove('online');
|
this.subtitleEl.classList.remove('online');
|
||||||
appSidebarRight.profileElements.subtitle.classList.remove('online');
|
profileElements.subtitle.classList.remove('online');
|
||||||
///////this.log('setPeerStatus', chat);
|
///////this.log('setPeerStatus', chat);
|
||||||
|
|
||||||
if(needClear) {
|
if(needClear) {
|
||||||
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = '';
|
this.subtitleEl.innerText = profileElements.subtitle.innerText = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
appProfileManager.getChatFull(chat.id).then((chatInfo: any) => {
|
appProfileManager.getChatFull(chat.id).then((chatInfo: any) => {
|
||||||
@ -904,7 +905,7 @@ export class AppImManager {
|
|||||||
if(participants_count) {
|
if(participants_count) {
|
||||||
let subtitle = numberWithCommas(participants_count) + ' ' + (isChannel ? 'followers' : 'members');
|
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;
|
if(participants_count < 2) return;
|
||||||
appChatsManager.getOnlines(chat.id).then(onlines => {
|
appChatsManager.getOnlines(chat.id).then(onlines => {
|
||||||
@ -912,7 +913,7 @@ export class AppImManager {
|
|||||||
subtitle += ', ' + numberWithCommas(onlines) + ' online';
|
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);
|
let user = appUsersManager.getUser(this.peerID);
|
||||||
|
|
||||||
if(this.myID == 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) {
|
} else if(user && user.status) {
|
||||||
let subtitle = appUsersManager.getUserStatusString(user.id);
|
let subtitle = appUsersManager.getUserStatusString(user.id);
|
||||||
|
|
||||||
if(subtitle == 'online') {
|
if(subtitle == 'online') {
|
||||||
this.subtitleEl.classList.add('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) {
|
if(this.typingUsers[this.peerID] == this.peerID) {
|
||||||
this.subtitleEl.innerText = 'typing...';
|
this.subtitleEl.innerText = 'typing...';
|
||||||
@ -939,13 +940,13 @@ export class AppImManager {
|
|||||||
|
|
||||||
if(subtitle != 'online') {
|
if(subtitle != 'online') {
|
||||||
this.subtitleEl.classList.remove('online');
|
this.subtitleEl.classList.remove('online');
|
||||||
appSidebarRight.profileElements.subtitle.classList.remove('online');
|
profileElements.subtitle.classList.remove('online');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.subtitleEl.innerText = 'bot';
|
this.subtitleEl.innerText = 'bot';
|
||||||
appSidebarRight.profileElements.subtitle.innerText = 'bot';
|
profileElements.subtitle.innerText = 'bot';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,8 +1051,8 @@ export class AppImManager {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else if(appSidebarRight.historyTabIDs[appSidebarRight.historyTabIDs.length - 1] == AppSidebarRight.SLIDERITEMSIDS.search) {
|
||||||
appSidebarRight.searchCloseBtn.click();
|
appSidebarRight.searchTab.closeBtn?.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
// set new
|
// set new
|
||||||
@ -1088,7 +1089,7 @@ export class AppImManager {
|
|||||||
const {promise, cached} = this.getHistory(lastMsgID, true, isJump, additionMsgID);
|
const {promise, cached} = this.getHistory(lastMsgID, true, isJump, additionMsgID);
|
||||||
|
|
||||||
if(!samePeer) {
|
if(!samePeer) {
|
||||||
appSidebarRight.setPeer(this.peerID);
|
appSidebarRight.sharedMediaTab.setPeer(this.peerID);
|
||||||
} else {
|
} else {
|
||||||
this.peerChanged = true;
|
this.peerChanged = true;
|
||||||
}
|
}
|
||||||
@ -1207,8 +1208,8 @@ export class AppImManager {
|
|||||||
//appSidebarRight.setLoadMutex(this.setPeerPromise);
|
//appSidebarRight.setLoadMutex(this.setPeerPromise);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
appSidebarRight.setLoadMutex(this.setPeerPromise);
|
appSidebarRight.sharedMediaTab.setLoadMutex(this.setPeerPromise);
|
||||||
appSidebarRight.loadSidebarMedia(true);
|
appSidebarRight.sharedMediaTab.loadSidebarMedia(true);
|
||||||
|
|
||||||
return this.setPeerPromise;
|
return this.setPeerPromise;
|
||||||
}
|
}
|
||||||
@ -1252,14 +1253,14 @@ export class AppImManager {
|
|||||||
let title = '';
|
let title = '';
|
||||||
if(this.peerID == this.myID) title = 'Saved Messages';
|
if(this.peerID == this.myID) title = 'Saved Messages';
|
||||||
else title = appPeersManager.getPeerTitle(this.peerID);
|
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.goDownBtn.classList.remove('hide');
|
||||||
|
|
||||||
this.setPeerStatus(true);
|
this.setPeerStatus(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
appSidebarRight.fillProfileElements();
|
appSidebarRight.sharedMediaTab.fillProfileElements();
|
||||||
|
|
||||||
$rootScope.$broadcast('peer_changed', this.peerID);
|
$rootScope.$broadcast('peer_changed', this.peerID);
|
||||||
}
|
}
|
||||||
@ -2536,8 +2537,8 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setMutedState(muted = false) {
|
public setMutedState(muted = false) {
|
||||||
appSidebarRight.profileElements.notificationsCheckbox.checked = !muted;
|
appSidebarRight.sharedMediaTab.profileElements.notificationsCheckbox.checked = !muted;
|
||||||
appSidebarRight.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
|
appSidebarRight.sharedMediaTab.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
|
||||||
|
|
||||||
if(appPeersManager.isBroadcast(this.peerID)) { // not human
|
if(appPeersManager.isBroadcast(this.peerID)) { // not human
|
||||||
this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
|
this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
|
||||||
|
@ -10,12 +10,12 @@ import VideoPlayer from "../mediaPlayer";
|
|||||||
import { renderImageFromUrl, parseMenuButtonsTo } from "../../components/misc";
|
import { renderImageFromUrl, parseMenuButtonsTo } from "../../components/misc";
|
||||||
import AvatarElement from "../../components/avatar";
|
import AvatarElement from "../../components/avatar";
|
||||||
import { LazyLoadQueueBase } from "../../components/lazyLoadQueue";
|
import { LazyLoadQueueBase } from "../../components/lazyLoadQueue";
|
||||||
import appForward from "../../components/appForward";
|
|
||||||
import { touchSupport } from "../config";
|
import { touchSupport } from "../config";
|
||||||
import appMediaPlaybackController from "../../components/appMediaPlaybackController";
|
import appMediaPlaybackController from "../../components/appMediaPlaybackController";
|
||||||
import { deferredPromise } from "../../helpers/cancellablePromise";
|
import { deferredPromise } from "../../helpers/cancellablePromise";
|
||||||
import mediaSizes from "../../helpers/mediaSizes";
|
import mediaSizes from "../../helpers/mediaSizes";
|
||||||
import { isSafari } from "../../helpers/userAgent";
|
import { isSafari } from "../../helpers/userAgent";
|
||||||
|
import appSidebarRight, { AppSidebarRight } from "./appSidebarRight";
|
||||||
|
|
||||||
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
|
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
|
||||||
// TODO: картинки "обрезаются" если возвращаются или появляются с места, где есть их перекрытие (топбар, поле ввода)
|
// TODO: картинки "обрезаются" если возвращаются или появляются с места, где есть их перекрытие (топбар, поле ввода)
|
||||||
@ -155,9 +155,9 @@ export class AppMediaViewer {
|
|||||||
this.loadMediaPromiseUp = this.loadMediaPromiseDown = null;
|
this.loadMediaPromiseUp = this.loadMediaPromiseDown = null;
|
||||||
this.setMoverPromise = null;
|
this.setMoverPromise = null;
|
||||||
|
|
||||||
if(appForward.container.classList.contains('active')) {
|
if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
appForward.close();
|
appSidebarRight.forwardTab.closeBtn.click();
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ export class AppMediaViewer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const forward = (e: MouseEvent) => {
|
const forward = (e: MouseEvent) => {
|
||||||
appForward.init([this.currentMessageID]);
|
appSidebarRight.forwardTab.open([this.currentMessageID]);
|
||||||
};
|
};
|
||||||
|
|
||||||
[this.buttons.forward, this.buttons["menu-forward"]].forEach(el => {
|
[this.buttons.forward, this.buttons["menu-forward"]].forEach(el => {
|
||||||
@ -853,8 +853,8 @@ export class AppMediaViewer {
|
|||||||
this.needLoadMore = needLoadMore;
|
this.needLoadMore = needLoadMore;
|
||||||
//this.loadMore = loadMore;
|
//this.loadMore = loadMore;
|
||||||
|
|
||||||
if(appForward.container.classList.contains('active')) {
|
if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) {
|
||||||
appForward.close();
|
appSidebarRight.forwardTab.closeBtn.click();
|
||||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,8 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
[AppSidebarLeft.SLIDERITEMSIDS.includedChats]: includedChatsTab,
|
[AppSidebarLeft.SLIDERITEMSIDS.includedChats]: includedChatsTab,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//this._selectTab(0); // make first tab as default
|
||||||
|
|
||||||
this.searchInput = new SearchInput('Telegram Search');
|
this.searchInput = new SearchInput('Telegram Search');
|
||||||
this.sidebarEl.querySelector('.item-main .sidebar-header').append(this.searchInput.container);
|
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 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 SidebarSlider from "../../components/slider";
|
||||||
import SearchInput from "../../components/searchInput";
|
|
||||||
import { horizontalMenu } from "../../components/horizontalMenu";
|
|
||||||
import AppStickersTab from "../../components/sidebarRight/stickers";
|
import AppStickersTab from "../../components/sidebarRight/stickers";
|
||||||
import AppPollResultsTab from "../../components/sidebarRight/pollResults";
|
import AppPollResultsTab from "../../components/sidebarRight/pollResults";
|
||||||
import AppGifsTab from "../../components/sidebarRight/gifs";
|
import AppGifsTab from "../../components/sidebarRight/gifs";
|
||||||
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
|
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
|
||||||
import { isSafari } from "../../helpers/userAgent";
|
import AppPrivateSearchTab from "../../components/sidebarRight/search";
|
||||||
|
import AppSharedMediaTab from "../../components/sidebarRight/sharedMedia";
|
||||||
const testScroll = false;
|
import AppForwardTab from "../../components/sidebarRight/forward";
|
||||||
|
|
||||||
const COLUMN_ACTIVE_CLASSNAME = 'is-right-column-shown';
|
const COLUMN_ACTIVE_CLASSNAME = 'is-right-column-shown';
|
||||||
|
|
||||||
let setText = (text: string, el: HTMLDivElement) => {
|
const sharedMediaTab = new AppSharedMediaTab();
|
||||||
window.requestAnimationFrame(() => {
|
const searchTab = new AppPrivateSearchTab();
|
||||||
if(el.childElementCount > 1) {
|
const forwardTab = new AppForwardTab();
|
||||||
el.firstElementChild.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
let p = document.createElement('p');
|
|
||||||
p.innerHTML = text;
|
|
||||||
el.prepend(p);
|
|
||||||
|
|
||||||
el.style.display = '';
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const stickersTab = new AppStickersTab();
|
const stickersTab = new AppStickersTab();
|
||||||
const pollResultsTab = new AppPollResultsTab();
|
const pollResultsTab = new AppPollResultsTab();
|
||||||
const gifsTab = new AppGifsTab();
|
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 {
|
export class AppSidebarRight extends SidebarSlider {
|
||||||
public static SLIDERITEMSIDS = {
|
public static SLIDERITEMSIDS = {
|
||||||
|
sharedMedia: 0,
|
||||||
search: 1,
|
search: 1,
|
||||||
forward: 2,
|
forward: 2,
|
||||||
stickers: 3,
|
stickers: 3,
|
||||||
@ -70,197 +27,32 @@ export class AppSidebarRight extends SidebarSlider {
|
|||||||
gifs: 5,
|
gifs: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
public profileContainer: HTMLDivElement;
|
public sharedMediaTab: AppSharedMediaTab;
|
||||||
public profileContentEl: HTMLDivElement;
|
public searchTab: AppPrivateSearchTab;
|
||||||
public contentContainer: HTMLDivElement;
|
public forwardTab: AppForwardTab;
|
||||||
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 stickersTab: AppStickersTab;
|
public stickersTab: AppStickersTab;
|
||||||
public pollResultsTab: AppPollResultsTab;
|
public pollResultsTab: AppPollResultsTab;
|
||||||
public gifsTab: AppGifsTab;
|
public gifsTab: AppGifsTab;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(document.getElementById('column-right') as HTMLElement, {
|
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.stickers]: stickersTab,
|
||||||
[AppSidebarRight.SLIDERITEMSIDS.pollResults]: pollResultsTab,
|
[AppSidebarRight.SLIDERITEMSIDS.pollResults]: pollResultsTab,
|
||||||
[AppSidebarRight.SLIDERITEMSIDS.gifs]: gifsTab
|
[AppSidebarRight.SLIDERITEMSIDS.gifs]: gifsTab
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
//this._selectTab(3);
|
//this._selectTab(3);
|
||||||
|
|
||||||
|
this.sharedMediaTab = sharedMediaTab;
|
||||||
|
this.searchTab = searchTab;
|
||||||
|
this.forwardTab = forwardTab;
|
||||||
this.stickersTab = stickersTab;
|
this.stickersTab = stickersTab;
|
||||||
this.pollResultsTab = pollResultsTab;
|
this.pollResultsTab = pollResultsTab;
|
||||||
this.gifsTab = gifsTab;
|
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) => {
|
mediaSizes.addListener('changeScreen', (from, to) => {
|
||||||
if(from !== undefined && to == ScreenSize.medium) {
|
if(from !== undefined && to == ScreenSize.medium) {
|
||||||
this.toggleSidebar(false);
|
this.toggleSidebar(false);
|
||||||
@ -268,29 +60,24 @@ export class AppSidebarRight extends SidebarSlider {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onTransitionStart = () => {
|
public onCloseTab(id: number) {
|
||||||
// Jolly Cobra's // Workaround for scrollable content flickering during animation.
|
if(!this.historyTabIDs.length) {
|
||||||
const container = this.scroll.container;
|
this.toggleSidebar(false);
|
||||||
if(container.style.overflowY !== 'hidden') {
|
|
||||||
const scrollBarWidth = container.offsetWidth - container.clientWidth;
|
|
||||||
container.style.overflowY = 'hidden';
|
|
||||||
container.style.paddingRight = `${scrollBarWidth}px`;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
private onTransitionEnd = () => {
|
super.onCloseTab(id);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* public selectTab(id: number) {
|
||||||
|
const res = super.selectTab(id);
|
||||||
|
|
||||||
|
if(id !== -1) {
|
||||||
|
this.toggleSidebar(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
} */
|
||||||
|
|
||||||
public toggleSidebar(enable?: boolean) {
|
public toggleSidebar(enable?: boolean) {
|
||||||
/////this.log('sidebarEl', this.sidebarEl, enable, isElementInViewport(this.sidebarEl));
|
/////this.log('sidebarEl', this.sidebarEl, enable, isElementInViewport(this.sidebarEl));
|
||||||
|
|
||||||
@ -310,6 +97,10 @@ export class AppSidebarRight extends SidebarSlider {
|
|||||||
|
|
||||||
if(!willChange) return Promise.resolve();
|
if(!willChange) return Promise.resolve();
|
||||||
|
|
||||||
|
if(!active && !this.historyTabIDs.length) {
|
||||||
|
this.selectTab(AppSidebarRight.SLIDERITEMSIDS.sharedMedia);
|
||||||
|
}
|
||||||
|
|
||||||
//console.log('sidebar selectTab', enable, willChange);
|
//console.log('sidebar selectTab', enable, willChange);
|
||||||
if(mediaSizes.isMobile) {
|
if(mediaSizes.isMobile) {
|
||||||
appImManager.selectTab(active ? 1 : 2);
|
appImManager.selectTab(active ? 1 : 2);
|
||||||
@ -354,10 +145,10 @@ export class AppSidebarRight extends SidebarSlider {
|
|||||||
(item.element.firstElementChild as HTMLElement).style.display = '';
|
(item.element.firstElementChild as HTMLElement).style.display = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(active) {
|
/* if(active) {
|
||||||
appForward.close();
|
appForward.close();
|
||||||
this.searchCloseBtn.click();
|
this.searchCloseBtn.click();
|
||||||
}
|
} */
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}, 200);
|
}, 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();
|
const appSidebarRight = new AppSidebarRight();
|
||||||
|
@ -16,7 +16,7 @@ export function dT () {
|
|||||||
return '[' + ((Date.now() - _logTimer) / 1000).toFixed(3) + ']';
|
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) {
|
if(!element) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -26,6 +26,9 @@ export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return isInDOM(element.parentNode as HTMLElement, parentNode);
|
return isInDOM(element.parentNode as HTMLElement, parentNode);
|
||||||
|
} */
|
||||||
|
export function isInDOM(element: Element): boolean {
|
||||||
|
return element?.isConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkDragEvent(e: any) {
|
export function checkDragEvent(e: any) {
|
||||||
|
@ -51,6 +51,10 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-icon {
|
||||||
|
overflow: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#forward-container {
|
#forward-container {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user