Fixed slider animation & added same animation to auth pages
This commit is contained in:
parent
4c500ada12
commit
43bc94b0c4
@ -1,4 +1,4 @@
|
||||
import { whichChild, findUpTag } from "../lib/utils";
|
||||
import { whichChild, findUpTag, cancelEvent } from "../lib/utils";
|
||||
|
||||
let rippleClickID = 0;
|
||||
export function ripple(elem: HTMLElement, callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(), onEnd: (id: number) => void = null) {
|
||||
@ -8,11 +8,17 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool
|
||||
elem.append(r);
|
||||
|
||||
elem.addEventListener('mousedown', (e) => {
|
||||
if(elem.dataset.ripple == '0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
let startTime = Date.now();
|
||||
let span = document.createElement('span');
|
||||
|
||||
let clickID = rippleClickID++;
|
||||
|
||||
console.log('ripple mousedown');
|
||||
|
||||
let handler = () => {
|
||||
let elapsedTime = Date.now() - startTime;
|
||||
if(elapsedTime < 700) {
|
||||
@ -135,12 +141,92 @@ export function putPreloader(elem: Element, returnDiv = false) {
|
||||
elem.innerHTML += html;
|
||||
}
|
||||
|
||||
export function horizontalMenu(tabs: HTMLUListElement, content: HTMLDivElement, onClick?: (id: number, tabContent: HTMLDivElement) => void, onTransitionEnd?: () => void) {
|
||||
export function horizontalMenu(tabs: HTMLUListElement, content: HTMLDivElement, onClick?: (id: number, tabContent: HTMLDivElement) => void, onTransitionEnd?: () => void, transitionTime = 300) {
|
||||
let hideTimeout: number = 0;
|
||||
let prevTabContent: HTMLDivElement = null;
|
||||
|
||||
let prevId = -1;
|
||||
let children = Array.from(content.children);
|
||||
let tabsChildren = tabs ? Array.from(tabs.children) : [];
|
||||
let activeInSlide: Set<Element> = new Set();
|
||||
|
||||
let selectTab = (id: number) => {
|
||||
if(id == prevId) return false;
|
||||
|
||||
let p = prevTabContent;
|
||||
|
||||
/* children.forEach(child => {
|
||||
if(child != p) {
|
||||
child.classList.remove('active');
|
||||
}
|
||||
}); */
|
||||
|
||||
let tabContent = content.children[id] as HTMLDivElement;
|
||||
tabContent.classList.add('active');
|
||||
|
||||
if(!activeInSlide.has(tabContent)) {
|
||||
activeInSlide.add(tabContent);
|
||||
}
|
||||
|
||||
//content.style.marginLeft = id > 0 ? (-id * 100) + '%' : '';
|
||||
let toRight = prevId < id;
|
||||
if(prevId != -1) {
|
||||
content.style.cssText = `width: ${activeInSlide.size * 100}%; will-change: width, transform; transform: translateX(-${100 - 100 / activeInSlide.size}%);`;
|
||||
|
||||
//////console.log('mambo rap setting', toRight);
|
||||
|
||||
content.classList.remove('animated');
|
||||
if(toRight) {
|
||||
content.classList.add('animated');
|
||||
} else {
|
||||
window.requestAnimationFrame(() => {
|
||||
content.classList.add('animated');
|
||||
content.style.transform = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(hideTimeout) clearTimeout(hideTimeout);
|
||||
if(p/* && false */) {
|
||||
//if(tabs) tabs.classList.add('disable-hover');
|
||||
|
||||
if(tabs) {
|
||||
tabsChildren.forEach((c, idx) => {
|
||||
if(idx != prevId && idx != id) {
|
||||
(c as HTMLElement).dataset.ripple = '0';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
hideTimeout = setTimeout(() => {
|
||||
children.forEach(child => {
|
||||
if(child != tabContent) {
|
||||
child.classList.remove('active');
|
||||
activeInSlide.delete(child);
|
||||
}
|
||||
});
|
||||
|
||||
if(tabs) {
|
||||
tabsChildren.forEach(c => {
|
||||
delete (c as HTMLElement).dataset.ripple;
|
||||
});
|
||||
}
|
||||
|
||||
content.classList.remove('animated');
|
||||
content.style.cssText = '';
|
||||
|
||||
hideTimeout = 0;
|
||||
|
||||
if(onTransitionEnd) onTransitionEnd();
|
||||
//if(tabs) tabs.classList.remove('disable-hover');
|
||||
}, transitionTime);
|
||||
}
|
||||
|
||||
prevId = id;
|
||||
prevTabContent = tabContent;
|
||||
};
|
||||
|
||||
if(tabs) {
|
||||
tabs.addEventListener('click', function(e) {
|
||||
let target = e.target as HTMLLIElement;
|
||||
|
||||
@ -148,12 +234,18 @@ export function horizontalMenu(tabs: HTMLUListElement, content: HTMLDivElement,
|
||||
target = findUpTag(target, 'LI');
|
||||
}
|
||||
|
||||
///////console.log('tabs click:', target);
|
||||
//console.log('tabs click:', target);
|
||||
|
||||
if(!target) return false;
|
||||
|
||||
let id = whichChild(target);
|
||||
let tabContent = content.children[id] as HTMLDivElement;
|
||||
|
||||
if(activeInSlide.size >= 2 && !activeInSlide.has(tabContent)) {
|
||||
cancelEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(onClick) onClick(id, tabContent);
|
||||
if(target.classList.contains('active') || id == prevId) {
|
||||
return false;
|
||||
@ -163,61 +255,13 @@ export function horizontalMenu(tabs: HTMLUListElement, content: HTMLDivElement,
|
||||
prev && prev.classList.remove('active');
|
||||
|
||||
target.classList.add('active');
|
||||
tabContent.classList.add('active');
|
||||
|
||||
/////console.log('mambo rap', prevId, id);
|
||||
|
||||
//content.style.marginLeft = id > 0 ? (-id * 100) + '%' : '';
|
||||
let toRight = prevId < id;
|
||||
if(prevId != -1) {
|
||||
content.style.width = '200%';
|
||||
|
||||
//////console.log('mambo rap setting', toRight);
|
||||
|
||||
content.classList.remove('animated');
|
||||
|
||||
if(toRight) {
|
||||
content.classList.add('animated');
|
||||
content.style.marginLeft = '-100%';
|
||||
} else {
|
||||
|
||||
content.style.marginLeft = '-100%';
|
||||
setTimeout(() => {
|
||||
content.classList.add('animated');
|
||||
content.style.marginLeft = '';
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
prevId = id;
|
||||
|
||||
let p = prevTabContent;
|
||||
clearTimeout(hideTimeout);
|
||||
if(p) hideTimeout = setTimeout(() => {
|
||||
if(toRight) {
|
||||
p.classList.remove('active');
|
||||
content.classList.remove('animated');
|
||||
content.style.width = '100%';
|
||||
}
|
||||
|
||||
/* content.style.marginLeft = '0%';
|
||||
content.style.width = '100%'; */
|
||||
|
||||
if(!toRight) {
|
||||
p.classList.remove('active');
|
||||
content.classList.remove('animated');
|
||||
content.style.width = '100%';
|
||||
}
|
||||
|
||||
content.style.marginLeft = '';
|
||||
|
||||
if(onTransitionEnd) onTransitionEnd();
|
||||
}, 200);
|
||||
|
||||
prevTabContent = tabContent;
|
||||
selectTab(id);
|
||||
});
|
||||
}
|
||||
|
||||
return selectTab;
|
||||
}
|
||||
|
||||
export function formatPhoneNumber(str: string) {
|
||||
str = str.replace(/\D/g, '');
|
||||
let phoneCode = str.slice(0, 6);
|
||||
|
@ -1,194 +0,0 @@
|
||||
//import { appImManager, appMessagesManager, appDialogsManager, apiUpdatesManager, appUsersManager } from "../lib/services";
|
||||
import { openBtnMenu } from "./misc";
|
||||
//import {stackBlurImage} from '../lib/StackBlur';
|
||||
import appSidebarLeft from "../lib/appManagers/appSidebarLeft";
|
||||
|
||||
export default () => import('../lib/services').then(services => {
|
||||
//console.log('included services', services);
|
||||
|
||||
let {appImManager, appMessagesManager, appDialogsManager, apiUpdatesManager, appUsersManager} = services;
|
||||
//export default () => {
|
||||
|
||||
let pageEl = document.body.getElementsByClassName('page-chats')[0] as HTMLDivElement;
|
||||
pageEl.style.display = '';
|
||||
|
||||
apiUpdatesManager.attach();
|
||||
|
||||
// @ts-ignore
|
||||
document.addEventListener('user_update', (e: CustomEvent) => {
|
||||
let userID = e.detail;
|
||||
|
||||
let user = appUsersManager.getUser(userID);
|
||||
|
||||
let dialog = appMessagesManager.getDialogByPeerID(user.id)[0];
|
||||
//console.log('updating user:', user, dialog);
|
||||
|
||||
if(dialog && !appUsersManager.isBot(dialog.peerID) && dialog.peerID != appImManager.myID) {
|
||||
let online = user.status && user.status._ == 'userStatusOnline';
|
||||
let dom = appDialogsManager.getDialogDom(dialog.peerID);
|
||||
|
||||
if(dom) {
|
||||
if(online) {
|
||||
dom.avatarDiv.classList.add('is-online');
|
||||
} else {
|
||||
dom.avatarDiv.classList.remove('is-online');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(appImManager.peerID == user.id) {
|
||||
appImManager.setPeerStatus();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
document.addEventListener('dialog_top', (e: CustomEvent) => {
|
||||
let dialog: any = e.detail;
|
||||
|
||||
appDialogsManager.setLastMessage(dialog);
|
||||
appDialogsManager.sortDom();
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
document.addEventListener('dialogs_multiupdate', (e: CustomEvent) => {
|
||||
let dialogs = e.detail;
|
||||
|
||||
let performed = 0;
|
||||
for(let id in dialogs) {
|
||||
let dialog = dialogs[id];
|
||||
|
||||
/////console.log('updating dialog:', dialog);
|
||||
|
||||
++performed;
|
||||
|
||||
if(!(dialog.peerID in appDialogsManager.doms)) {
|
||||
appDialogsManager.addDialog(dialog);
|
||||
continue;
|
||||
}
|
||||
|
||||
appDialogsManager.setLastMessage(dialog);
|
||||
}
|
||||
|
||||
if(performed/* && false */) {
|
||||
/////////console.log('will sortDom');
|
||||
appDialogsManager.sortDom();
|
||||
appDialogsManager.sortDom(true);
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
document.addEventListener('dialog_unread', (e: CustomEvent) => {
|
||||
let info: {
|
||||
peerID: number,
|
||||
count: number
|
||||
} = e.detail;
|
||||
|
||||
let dialog = appMessagesManager.getDialogByPeerID(info.peerID)[0];
|
||||
if(dialog) {
|
||||
appDialogsManager.setUnreadMessages(dialog);
|
||||
|
||||
if(dialog.peerID == appImManager.peerID) {
|
||||
appImManager.updateUnreadByDialog(dialog);
|
||||
}
|
||||
}
|
||||
});
|
||||
/*
|
||||
loadDialogs().then(result => {
|
||||
//appImManager.setScroll(chatScroll);
|
||||
});
|
||||
return;
|
||||
*/
|
||||
|
||||
|
||||
/* function placeCaretAfterNode(node: HTMLElement) {
|
||||
if (typeof window.getSelection != "undefined") {
|
||||
var range = document.createRange();
|
||||
range.setStartAfter(node);
|
||||
range.collapse(true);
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
}
|
||||
|
||||
messageInput.onclick = (e) => {
|
||||
let target = e.target as HTMLElement;
|
||||
if(target.classList.contains('emoji-inner')) {
|
||||
placeCaretAfterNode(target.parentElement);
|
||||
} else if(target.classList.contains('emoji-sizer')) {
|
||||
placeCaretAfterNode(target);
|
||||
}
|
||||
console.log('lol', target);
|
||||
}; */
|
||||
|
||||
/* window.addEventListener('click', function(this, e) {
|
||||
// @ts-ignore
|
||||
let isInput = e.target.tagName == 'INPUT';
|
||||
if(!isInput && !window.getSelection().toString()) {
|
||||
console.log('click');
|
||||
messageInput.focus();
|
||||
}
|
||||
}); */
|
||||
|
||||
/* fetch('assets/img/camomile.jpg')
|
||||
.then(res => res.blob())
|
||||
.then(blob => {
|
||||
let img = new Image();
|
||||
let url = URL.createObjectURL(blob);
|
||||
img.src = url;
|
||||
img.onload = () => {
|
||||
let id = 'chat-background-canvas';
|
||||
var canvas = document.getElementById(id) as HTMLCanvasElement;
|
||||
//URL.revokeObjectURL(url);
|
||||
|
||||
let elements = ['.chat-container'].map(selector => {
|
||||
return document.querySelector(selector) as HTMLDivElement;
|
||||
});
|
||||
|
||||
stackBlurImage(img, id, 15, 0);
|
||||
|
||||
canvas.toBlob(blob => {
|
||||
//let dataUrl = canvas.toDataURL('image/jpeg', 1);
|
||||
let dataUrl = URL.createObjectURL(blob);
|
||||
|
||||
elements.forEach(el => {
|
||||
el.style.backgroundImage = 'url(' + dataUrl + ')';
|
||||
});
|
||||
}, 'image/jpeg', 1);
|
||||
};
|
||||
}); */
|
||||
|
||||
/* toggleEmoticons.onclick = (e) => {
|
||||
if(!emoticonsDropdown) {
|
||||
emoticonsDropdown = initEmoticonsDropdown(pageEl, appImManager,
|
||||
appMessagesManager, messageInput, toggleEmoticons);
|
||||
} else {
|
||||
emoticonsDropdown.classList.toggle('active');
|
||||
}
|
||||
|
||||
toggleEmoticons.classList.toggle('active');
|
||||
}; */
|
||||
|
||||
Array.from(document.getElementsByClassName('btn-menu-toggle')).forEach((el) => {
|
||||
el.addEventListener('click', (e) => {
|
||||
//console.log('click pageIm');
|
||||
if(!el.classList.contains('btn-menu-toggle')) return false;
|
||||
|
||||
//window.removeEventListener('mousemove', onMouseMove);
|
||||
let openedMenu = el.querySelector('.btn-menu') as HTMLDivElement;
|
||||
e.cancelBubble = true;
|
||||
|
||||
if(el.classList.contains('menu-open')) {
|
||||
el.classList.remove('menu-open');
|
||||
openedMenu.classList.remove('active');
|
||||
} else {
|
||||
openBtnMenu(openedMenu);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
appSidebarLeft.loadDialogs().then(result => {
|
||||
//appSidebarLeft.onChatsScroll();
|
||||
appSidebarLeft.loadDialogs(true);
|
||||
});
|
||||
});
|
@ -3,7 +3,6 @@ import CryptoWorker from '../lib/crypto/cryptoworker';
|
||||
import LottieLoader from '../lib/lottieLoader';
|
||||
import appStickersManager from "../lib/appManagers/appStickersManager";
|
||||
import appDocsManager from "../lib/appManagers/appDocsManager";
|
||||
import {AppImManager} from "../lib/appManagers/appImManager";
|
||||
import { formatBytes } from "../lib/utils";
|
||||
import ProgressivePreloader from './preloader';
|
||||
import LazyLoadQueue from './lazyLoadQueue';
|
||||
@ -60,9 +59,21 @@ export type MTPhotoSize = {
|
||||
bytes?: Uint8Array // if type == 'i'
|
||||
};
|
||||
|
||||
export function wrapVideo(this: AppImManager, doc: MTDocument, container: HTMLDivElement, message: any, justLoader = true, preloader?: ProgressivePreloader, controls = true, round = false, boxWidth = 380, boxHeight = 380, withTail = false, isOut = false) {
|
||||
export function wrapVideo({doc, container, message, justLoader, preloader, round, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue}: {
|
||||
doc: MTDocument,
|
||||
container: HTMLDivElement,
|
||||
message: any,
|
||||
justLoader: boolean,
|
||||
preloader?: ProgressivePreloader,
|
||||
round: boolean,
|
||||
boxWidth: number,
|
||||
boxHeight: number,
|
||||
withTail?: boolean,
|
||||
isOut?: boolean,
|
||||
middleware: () => boolean,
|
||||
lazyLoadQueue: LazyLoadQueue
|
||||
}) {
|
||||
let img: HTMLImageElement | SVGImageElement;
|
||||
let peerID = this.peerID;
|
||||
|
||||
if(withTail) {
|
||||
img = wrapMediaWithTail(doc, message, container, boxWidth, boxHeight, isOut);
|
||||
@ -104,8 +115,7 @@ export function wrapVideo(this: AppImManager, doc: MTDocument, container: HTMLDi
|
||||
preloader.attach(container, true, promise);
|
||||
|
||||
return promise.then(blob => {
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
if(!middleware()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -141,7 +151,7 @@ export function wrapVideo(this: AppImManager, doc: MTDocument, container: HTMLDi
|
||||
};
|
||||
|
||||
if(doc.type == 'gif' || true) { // extra fix
|
||||
return doc.downloaded ? loadVideo() : this.lazyLoadQueue.push({div: container, load: loadVideo, wasSeen: true});
|
||||
return doc.downloaded ? loadVideo() : lazyLoadQueue.push({div: container, load: loadVideo, wasSeen: true});
|
||||
} /* else { // if video
|
||||
let load = () => appPhotosManager.preloadPhoto(doc).then((blob) => {
|
||||
if((this.peerID ? this.peerID : this.currentMessageID) != peerID) {
|
||||
@ -481,9 +491,7 @@ function wrapMediaWithTail(photo: any, message: {mid: number, message: string},
|
||||
return image;
|
||||
}
|
||||
|
||||
export async function wrapPhoto(this: AppImManager, photoID: string, message: any, container: HTMLDivElement, boxWidth = 380, boxHeight = 380, withTail = true, isOut = false) {
|
||||
let peerID = this.peerID;
|
||||
|
||||
export async function wrapPhoto(photoID: string, message: any, container: HTMLDivElement, boxWidth = 380, boxHeight = 380, withTail = true, isOut = false, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean) {
|
||||
let photo = appPhotosManager.getPhoto(photoID);
|
||||
|
||||
let size: MTPhotoSize;
|
||||
@ -512,10 +520,7 @@ export async function wrapPhoto(this: AppImManager, photoID: string, message: an
|
||||
}
|
||||
|
||||
return promise.then(() => {
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
if(!middleware()) return;
|
||||
|
||||
renderImageFromUrl(image, photo.url);
|
||||
});
|
||||
@ -523,7 +528,7 @@ export async function wrapPhoto(this: AppImManager, photoID: string, message: an
|
||||
|
||||
/////////console.log('wrapPhoto', load, container, image);
|
||||
|
||||
return photo.downloaded ? load() : this.lazyLoadQueue.push({div: container, load: load, wasSeen: true});
|
||||
return photo.downloaded ? load() : lazyLoadQueue.push({div: container, load: load, wasSeen: true});
|
||||
}
|
||||
|
||||
export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: () => boolean, lazyLoadQueue?: LazyLoadQueue, group?: string, canvas?: boolean, play = false, onlyThumb = false) {
|
||||
|
@ -1,14 +1,13 @@
|
||||
import apiManager from "../mtproto/apiManager";
|
||||
import apiFileManager from '../mtproto/apiFileManager';
|
||||
import { $rootScope, langPack, findUpClassName } from "../utils";
|
||||
import { langPack, findUpClassName, $rootScope } from "../utils";
|
||||
import appImManager, { AppImManager } from "./appImManager";
|
||||
import appPeersManager from './appPeersManager';
|
||||
import appMessagesManager from "./appMessagesManager";
|
||||
import appMessagesManager, { AppMessagesManager } from "./appMessagesManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
import { ripple, renderImageFromUrl } from "../../components/misc";
|
||||
import appSidebarLeft from "./appSidebarLeft";
|
||||
import { ripple, putPreloader } from "../../components/misc";
|
||||
import Scrollable from "../../components/scrollable";
|
||||
import appProfileManager from "./appProfileManager";
|
||||
import { logger } from "../polyfill";
|
||||
|
||||
type DialogDom = {
|
||||
avatarDiv: HTMLDivElement,
|
||||
@ -22,6 +21,8 @@ type DialogDom = {
|
||||
listEl: HTMLLIElement
|
||||
};
|
||||
|
||||
let testScroll = false;
|
||||
|
||||
export class AppDialogsManager {
|
||||
public chatList = document.getElementById('dialogs') as HTMLUListElement;
|
||||
public chatListArchived = document.getElementById('dialogs-archived') as HTMLUListElement;
|
||||
@ -31,42 +32,228 @@ export class AppDialogsManager {
|
||||
public chatsArchivedHidden: Scrollable["hiddenElements"];
|
||||
public chatsArchivedVisible: Scrollable["visibleElements"];
|
||||
|
||||
public myID = 0;
|
||||
public doms: {[peerID: number]: DialogDom} = {};
|
||||
public domsArchived: {[peerID: number]: DialogDom} = {};
|
||||
public lastActiveListElement: HTMLElement = null;
|
||||
|
||||
public savedAvatarURLs: {[peerID: number]: string} = {};
|
||||
|
||||
private rippleCallback: (value?: boolean | PromiseLike<boolean>) => void = null;
|
||||
private lastClickID = 0;
|
||||
private lastGoodClickID = 0;
|
||||
|
||||
public chatsArchivedContainer = document.getElementById('chats-archived-container') as HTMLDivElement;
|
||||
public chatsContainer = document.getElementById('chats-container') as HTMLDivElement;
|
||||
private chatsArchivedOffsetIndex = 0;
|
||||
private chatsOffsetIndex = 0;
|
||||
private chatsPreloader: HTMLDivElement;
|
||||
//private chatsLoadCount = 0;
|
||||
//private loadDialogsPromise: Promise<any>;
|
||||
private loadDialogsPromise: ReturnType<AppMessagesManager["getConversations"]>;
|
||||
|
||||
private loadedAll = false;
|
||||
private loadedArchivedAll = false;
|
||||
|
||||
public scroll: Scrollable = null;
|
||||
public scrollArchived: Scrollable = null;
|
||||
|
||||
private log = logger('DIALOGS');
|
||||
|
||||
constructor() {
|
||||
this.chatsPreloader = putPreloader(null, true);
|
||||
//this.chatsContainer.append(this.chatsPreloader);
|
||||
|
||||
this.pinnedDelimiter = document.createElement('div');
|
||||
this.pinnedDelimiter.classList.add('pinned-delimiter');
|
||||
this.pinnedDelimiter.appendChild(document.createElement('span'));
|
||||
|
||||
apiManager.getUserID().then((id) => {
|
||||
this.myID = id;
|
||||
});
|
||||
//this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
|
||||
|
||||
$rootScope.$on('user_auth', (e: CustomEvent) => {
|
||||
let userAuth = e.detail;
|
||||
this.myID = userAuth ? userAuth.id : 0;
|
||||
});
|
||||
let splitOffset = 1110;
|
||||
|
||||
$rootScope.$on('history_request', () => { // will call at history request api or cache RENDERED!
|
||||
if(this.rippleCallback) {
|
||||
this.rippleCallback();
|
||||
this.rippleCallback = null;
|
||||
}
|
||||
});
|
||||
this.scroll = new Scrollable(this.chatsContainer, 'y', splitOffset, 'CL', this.chatList, 500);
|
||||
this.scroll.setVirtualContainer(this.chatList);
|
||||
this.scroll.onScrolledBottom = this.onChatsScroll.bind(this);
|
||||
this.chatsHidden = this.scroll.hiddenElements;
|
||||
this.chatsVisible = this.scroll.visibleElements;
|
||||
|
||||
this.scrollArchived = new Scrollable(this.chatsArchivedContainer, 'y', splitOffset, 'CLA', this.chatListArchived, 500);
|
||||
this.scrollArchived.setVirtualContainer(this.chatListArchived);
|
||||
this.scrollArchived.onScrolledBottom = this.onChatsArchivedScroll.bind(this);
|
||||
this.chatsArchivedHidden = this.scrollArchived.hiddenElements;
|
||||
this.chatsArchivedVisible = this.scrollArchived.visibleElements;
|
||||
//this.scrollArchived.container.addEventListener('scroll', this.onChatsArchivedScroll.bind(this));
|
||||
|
||||
//let chatClosedDiv = document.getElementById('chat-closed');
|
||||
|
||||
this.setListClickListener(this.chatList);
|
||||
this.setListClickListener(this.chatListArchived);
|
||||
|
||||
if(testScroll) {
|
||||
for(let i = 0; i < 1000; ++i) {
|
||||
let li = document.createElement('li');
|
||||
li.dataset.id = '' + i;
|
||||
li.innerHTML = `<div class="rp"><div class="user-avatar" style="background-color: rgb(166, 149, 231); font-size: 0px;"><img src="#"></div><div class="user-caption"><p><span class="user-title">${i}</span><span><span class="message-status"></span><span class="message-time">18:33</span></span></p><p><span class="user-last-message"><b>-_-_-_-: </b>qweasd</span><span></span></p></div></div>`;
|
||||
this.scroll.append(li);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
//this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
|
||||
|
||||
setTimeout(() => {
|
||||
this.onChatsArchivedScroll();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
$rootScope.$on('user_update', (e: CustomEvent) => {
|
||||
let userID = e.detail;
|
||||
|
||||
let user = appUsersManager.getUser(userID);
|
||||
|
||||
let dialog = appMessagesManager.getDialogByPeerID(user.id)[0];
|
||||
//console.log('updating user:', user, dialog);
|
||||
|
||||
if(dialog && !appUsersManager.isBot(dialog.peerID) && dialog.peerID != $rootScope.myID) {
|
||||
let online = user.status && user.status._ == 'userStatusOnline';
|
||||
let dom = this.getDialogDom(dialog.peerID);
|
||||
|
||||
if(dom) {
|
||||
if(online) {
|
||||
dom.avatarDiv.classList.add('is-online');
|
||||
} else {
|
||||
dom.avatarDiv.classList.remove('is-online');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(appImManager.peerID == user.id) {
|
||||
appImManager.setPeerStatus();
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$on('dialog_top', (e: CustomEvent) => {
|
||||
let dialog: any = e.detail;
|
||||
|
||||
this.setLastMessage(dialog);
|
||||
this.sortDom();
|
||||
});
|
||||
|
||||
$rootScope.$on('dialogs_multiupdate', (e: CustomEvent) => {
|
||||
let dialogs = e.detail;
|
||||
|
||||
let performed = 0;
|
||||
for(let id in dialogs) {
|
||||
let dialog = dialogs[id];
|
||||
|
||||
/////console.log('updating dialog:', dialog);
|
||||
|
||||
++performed;
|
||||
|
||||
if(!(dialog.peerID in this.doms)) {
|
||||
this.addDialog(dialog);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.setLastMessage(dialog);
|
||||
}
|
||||
|
||||
if(performed/* && false */) {
|
||||
/////////console.log('will sortDom');
|
||||
this.sortDom();
|
||||
this.sortDom(true);
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$on('dialog_unread', (e: CustomEvent) => {
|
||||
let info: {
|
||||
peerID: number,
|
||||
count: number
|
||||
} = e.detail;
|
||||
|
||||
let dialog = appMessagesManager.getDialogByPeerID(info.peerID)[0];
|
||||
if(dialog) {
|
||||
this.setUnreadMessages(dialog);
|
||||
|
||||
if(dialog.peerID == appImManager.peerID) {
|
||||
appImManager.updateUnreadByDialog(dialog);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.loadDialogs().then(result => {
|
||||
//appSidebarLeft.onChatsScroll();
|
||||
this.loadDialogs(true);
|
||||
});
|
||||
}
|
||||
|
||||
public async loadDialogs(archived = false) {
|
||||
if(testScroll) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.loadDialogsPromise/* || 1 == 1 */) return this.loadDialogsPromise;
|
||||
|
||||
(archived ? this.chatsArchivedContainer : this.chatsContainer).append(this.chatsPreloader);
|
||||
|
||||
//let offset = appMessagesManager.generateDialogIndex();/* appMessagesManager.dialogsNum */;
|
||||
|
||||
let offset = archived ? this.chatsArchivedOffsetIndex : this.chatsOffsetIndex;
|
||||
//let offset = 0;
|
||||
|
||||
let scroll = archived ? this.scrollArchived : this.scroll;
|
||||
scroll.lock();
|
||||
|
||||
try {
|
||||
console.time('getDialogs time');
|
||||
|
||||
let loadCount = 50/*this.chatsLoadCount */;
|
||||
this.loadDialogsPromise = appMessagesManager.getConversations('', offset, loadCount, +archived);
|
||||
|
||||
let result = await this.loadDialogsPromise;
|
||||
|
||||
console.timeEnd('getDialogs time');
|
||||
|
||||
if(result && result.dialogs && result.dialogs.length) {
|
||||
let index = result.dialogs[result.dialogs.length - 1].index;
|
||||
|
||||
if(archived) this.chatsArchivedOffsetIndex = index;
|
||||
else this.chatsOffsetIndex = index;
|
||||
|
||||
result.dialogs.forEach((dialog: any) => {
|
||||
this.addDialog(dialog);
|
||||
});
|
||||
}
|
||||
|
||||
if(!result.dialogs.length || (archived ? this.scrollArchived.length == result.count : this.scroll.length == result.count)) { // loaded all
|
||||
if(archived) this.loadedArchivedAll = true;
|
||||
else this.loadedAll = true;
|
||||
}
|
||||
|
||||
/* if(archived) {
|
||||
let count = result.count;
|
||||
this.archivedCount.innerText = '' + count;
|
||||
} */
|
||||
|
||||
this.log('getDialogs ' + loadCount + ' dialogs by offset:', offset, result, this.scroll.length);
|
||||
this.scroll.onScroll();
|
||||
} catch(err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
|
||||
this.chatsPreloader.remove();
|
||||
this.loadDialogsPromise = undefined;
|
||||
scroll.unlock();
|
||||
}
|
||||
|
||||
public onChatsScroll() {
|
||||
if(this.loadedAll || this.scroll.hiddenElements.down.length > 0 || this.loadDialogsPromise/* || 1 == 1 */) return;
|
||||
|
||||
this.loadDialogs();
|
||||
}
|
||||
|
||||
public onChatsArchivedScroll() {
|
||||
if(this.loadedArchivedAll || this.scrollArchived.hiddenElements.down.length > 0 || this.loadDialogsPromise/* || 1 == 1 */) return;
|
||||
|
||||
this.loadDialogs(true);
|
||||
}
|
||||
|
||||
public setListClickListener(list: HTMLUListElement, onFound?: () => void) {
|
||||
@ -142,94 +329,6 @@ export class AppDialogsManager {
|
||||
});
|
||||
}
|
||||
|
||||
// peerID == peerID || title
|
||||
public async loadDialogPhoto(div: HTMLDivElement, peerID: number, isDialog = false, title = ''): Promise<boolean> {
|
||||
let inputPeer: any;
|
||||
let location: any;
|
||||
if(peerID) {
|
||||
inputPeer = appPeersManager.getInputPeerByID(peerID);
|
||||
location = appPeersManager.getPeerPhoto(peerID);
|
||||
}
|
||||
|
||||
//console.log('loadDialogPhoto location:', location, inputPeer);
|
||||
|
||||
if(peerID == this.myID && (isDialog || $rootScope.selectedPeerID == this.myID)) {
|
||||
if(div.firstChild) {
|
||||
div.firstChild.remove();
|
||||
}
|
||||
|
||||
div.style.backgroundColor = '';
|
||||
div.classList.add('tgico-savedmessages');
|
||||
div.classList.remove('tgico-avatar_deletedaccount');
|
||||
return true;
|
||||
}
|
||||
|
||||
if(peerID) {
|
||||
let user = appUsersManager.getUser(peerID);
|
||||
if(user && user.pFlags && user.pFlags.deleted) {
|
||||
if(div.firstChild) {
|
||||
div.firstChild.remove();
|
||||
}
|
||||
|
||||
div.style.backgroundColor = '';
|
||||
div.classList.add('tgico-avatar_deletedaccount');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//if(!location || location.empty || !location.photo_small) {
|
||||
if(div.firstChild) {
|
||||
div.firstChild.remove();
|
||||
}
|
||||
|
||||
let color = '';
|
||||
if(peerID && peerID != this.myID) {
|
||||
color = appPeersManager.getPeerColorByID(peerID);
|
||||
}
|
||||
|
||||
div.classList.remove('tgico-savedmessages', 'tgico-avatar_deletedaccount');
|
||||
div.style.backgroundColor = color;
|
||||
|
||||
let abbrSplitted = (!title && peerID ? appPeersManager.getPeerTitle(peerID, true) : title).split(' ');
|
||||
let abbr = (abbrSplitted.length == 2 ?
|
||||
abbrSplitted[0][0] + abbrSplitted[1][0] :
|
||||
abbrSplitted[0][0]).toUpperCase();
|
||||
|
||||
//div.innerText = peer.initials.toUpperCase();
|
||||
div.innerText = abbr.toUpperCase();
|
||||
//return Promise.resolve(true);
|
||||
//}
|
||||
|
||||
if(!location || location.empty || !location.photo_small) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!this.savedAvatarURLs[peerID]) {
|
||||
let res = await apiFileManager.downloadSmallFile({
|
||||
_: 'inputPeerPhotoFileLocation',
|
||||
dc_id: location.dc_id,
|
||||
flags: 0,
|
||||
peer: inputPeer,
|
||||
volume_id: location.photo_small.volume_id,
|
||||
local_id: location.photo_small.local_id
|
||||
});
|
||||
|
||||
this.savedAvatarURLs[peerID] = URL.createObjectURL(res);
|
||||
}
|
||||
|
||||
let img = new Image();
|
||||
renderImageFromUrl(img, this.savedAvatarURLs[peerID]);
|
||||
div.innerHTML = '';
|
||||
//div.style.fontSize = '0'; // need
|
||||
//div.style.backgroundColor = '';
|
||||
|
||||
//window.requestAnimationFrame(() => {
|
||||
div.append(img);
|
||||
//});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public sortDom(archived = false) {
|
||||
//return;
|
||||
//if(archived) return;
|
||||
@ -299,7 +398,7 @@ export class AppDialogsManager {
|
||||
|
||||
let child = concated.find(obj => obj.element == dom.listEl);
|
||||
if(!child) {
|
||||
return console.error('no child by listEl:', dom.listEl, archived, concated);
|
||||
return this.log.error('no child by listEl:', dom.listEl, archived, concated);
|
||||
}
|
||||
|
||||
if(inUpper.length < hiddenLength) {
|
||||
@ -412,7 +511,7 @@ export class AppDialogsManager {
|
||||
let senderBold = document.createElement('b');
|
||||
|
||||
let str = '';
|
||||
if(sender.id == this.myID) {
|
||||
if(sender.id == $rootScope.myID) {
|
||||
str = 'You';
|
||||
} else {
|
||||
str = sender.first_name || sender.last_name || sender.username;
|
||||
@ -459,7 +558,7 @@ export class AppDialogsManager {
|
||||
dom.statusSpan.innerHTML = '';
|
||||
let lastMessage = appMessagesManager.getMessage(dialog.top_message);
|
||||
if(lastMessage._ != 'messageEmpty' &&
|
||||
lastMessage.from_id == this.myID && lastMessage.peerID != this.myID &&
|
||||
lastMessage.from_id == $rootScope.myID && lastMessage.peerID != $rootScope.myID &&
|
||||
dialog.read_outbox_max_id) { // maybe comment, 06.20.2020
|
||||
let outgoing = (lastMessage.pFlags && lastMessage.pFlags.unread)
|
||||
/* && dialog.read_outbox_max_id != 0 */; // maybe uncomment, 31.01.2020
|
||||
@ -497,7 +596,7 @@ export class AppDialogsManager {
|
||||
return acc;
|
||||
}, 0);
|
||||
|
||||
appSidebarLeft.archivedCount.innerText = '' + sum;
|
||||
$rootScope.$broadcast('dialogs_archived_unread', {count: sum});
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,7 +619,7 @@ export class AppDialogsManager {
|
||||
let avatarDiv = document.createElement('div');
|
||||
avatarDiv.classList.add('user-avatar');
|
||||
|
||||
if(drawStatus && peerID != this.myID) {
|
||||
if(drawStatus && peerID != $rootScope.myID) {
|
||||
let peer = dialog.peer;
|
||||
|
||||
switch(peer._) {
|
||||
@ -544,12 +643,12 @@ export class AppDialogsManager {
|
||||
let titleSpan = document.createElement('span');
|
||||
titleSpan.classList.add('user-title');
|
||||
|
||||
if(peerID == this.myID) {
|
||||
if(peerID == $rootScope.myID) {
|
||||
title = 'Saved Messages';
|
||||
}
|
||||
|
||||
//console.log('trying to load photo for:', title);
|
||||
this.loadDialogPhoto(avatarDiv, dialog.peerID, true);
|
||||
appProfileManager.putPhoto(avatarDiv, dialog.peerID, true);
|
||||
|
||||
titleSpan.innerHTML = title;
|
||||
//p.classList.add('')
|
||||
@ -565,7 +664,7 @@ export class AppDialogsManager {
|
||||
paddingDiv.append(avatarDiv, captionDiv);
|
||||
|
||||
ripple(paddingDiv, (id) => {
|
||||
console.log('dialogs click element');
|
||||
this.log('dialogs click element');
|
||||
this.lastClickID = id;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -617,10 +716,10 @@ export class AppDialogsManager {
|
||||
|
||||
if(!container) {
|
||||
if(dialog.folder_id && dialog.folder_id == 1) {
|
||||
appSidebarLeft.scrollArchived.append(li);
|
||||
this.scrollArchived.append(li);
|
||||
this.domsArchived[dialog.peerID] = dom;
|
||||
} else {
|
||||
appSidebarLeft.scroll.append(li);
|
||||
this.scroll.append(li);
|
||||
this.doms[dialog.peerID] = dom;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ export class AppImManager {
|
||||
this.popupDeleteMessage.cancelBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-close') as HTMLButtonElement;
|
||||
|
||||
apiManager.getUserID().then((id) => {
|
||||
this.myID = id;
|
||||
this.myID = $rootScope.myID = id;
|
||||
});
|
||||
|
||||
this.topbar = document.getElementById('topbar') as HTMLDivElement;
|
||||
@ -128,7 +128,7 @@ export class AppImManager {
|
||||
|
||||
$rootScope.$on('user_auth', (e: CustomEvent) => {
|
||||
let userAuth = e.detail;
|
||||
this.myID = userAuth ? userAuth.id : 0;
|
||||
this.myID = $rootScope.myID = userAuth ? userAuth.id : 0;
|
||||
});
|
||||
|
||||
// will call when message is sent (only 1)
|
||||
@ -558,6 +558,7 @@ export class AppImManager {
|
||||
setInterval(() => this.setPeerStatus(), 60e3);
|
||||
|
||||
this.setScroll();
|
||||
apiUpdatesManager.attach();
|
||||
}
|
||||
|
||||
public deleteMessages(revoke = false) {
|
||||
@ -882,8 +883,8 @@ export class AppImManager {
|
||||
|
||||
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null;
|
||||
//////this.log('setPeer peerID:', this.peerID, dialog, lastMsgID);
|
||||
appDialogsManager.loadDialogPhoto(this.avatarEl, this.peerID);
|
||||
appDialogsManager.loadDialogPhoto(appSidebarRight.profileElements.avatar, this.peerID);
|
||||
appProfileManager.putPhoto(this.avatarEl, this.peerID);
|
||||
appProfileManager.putPhoto(appSidebarRight.profileElements.avatar, this.peerID);
|
||||
|
||||
this.firstTopMsgID = dialog ? dialog.top_message : 0;
|
||||
|
||||
@ -1248,7 +1249,9 @@ export class AppImManager {
|
||||
|
||||
bubble.classList.add('hide-name', 'photo');
|
||||
|
||||
wrapPhoto.call(this, photo.id, message, attachmentDiv, undefined, undefined, true, our);
|
||||
wrapPhoto(photo.id, message, attachmentDiv, undefined, undefined, true, our, this.lazyLoadQueue, () => {
|
||||
return this.peerID == peerID;
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1291,7 +1294,20 @@ export class AppImManager {
|
||||
if(doc.type == 'gif' || doc.type == 'video') {
|
||||
//if(doc.size <= 20e6) {
|
||||
bubble.classList.add('video');
|
||||
wrapVideo.call(this, doc, preview, message, true, null, false, false, 380, 300);
|
||||
wrapVideo({
|
||||
doc,
|
||||
container: preview,
|
||||
message,
|
||||
justLoader: true,
|
||||
preloader: null,
|
||||
round: false,
|
||||
boxWidth: 380,
|
||||
boxHeight: 300,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware: () => {
|
||||
return this.peerID == peerID;
|
||||
}
|
||||
});
|
||||
//}
|
||||
} else {
|
||||
doc = null;
|
||||
@ -1301,7 +1317,9 @@ export class AppImManager {
|
||||
if(webpage.photo && !doc) {
|
||||
bubble.classList.add('photo');
|
||||
|
||||
wrapPhoto.call(this, webpage.photo.id, message, preview, 380, 300, false);
|
||||
wrapPhoto(webpage.photo.id, message, preview, 380, 300, false, null, this.lazyLoadQueue, () => {
|
||||
return this.peerID == peerID;
|
||||
});
|
||||
}
|
||||
|
||||
if(preview) {
|
||||
@ -1366,7 +1384,23 @@ export class AppImManager {
|
||||
}
|
||||
|
||||
bubble.classList.add('hide-name', 'video');
|
||||
wrapVideo.call(this, doc, attachmentDiv, message, true, null, false, doc.type == 'round', 380, 380, doc.type != 'round', our);
|
||||
//wrapVideo.call(this, doc, attachmentDiv, message, true, null, false, doc.type == 'round', 380, 380, doc.type != 'round', our);
|
||||
wrapVideo({
|
||||
doc,
|
||||
container: attachmentDiv,
|
||||
message,
|
||||
justLoader: true,
|
||||
preloader: null,
|
||||
round: doc.type == 'round',
|
||||
boxWidth: 380,
|
||||
boxHeight: 380,
|
||||
withTail: doc.type != 'round',
|
||||
isOut: our,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware: () => {
|
||||
return this.peerID == peerID;
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
} else if(doc.mime_type == 'audio/ogg') {
|
||||
@ -1479,11 +1513,11 @@ export class AppImManager {
|
||||
|
||||
/////////this.log('exec loadDialogPhoto', message);
|
||||
if(message.fromID) { // if no - user hidden
|
||||
appDialogsManager.loadDialogPhoto(avatarDiv, message.fromID);
|
||||
appProfileManager.putPhoto(avatarDiv, message.fromID);
|
||||
} else if(!title && message.fwd_from && message.fwd_from.from_name) {
|
||||
title = message.fwd_from.from_name;
|
||||
|
||||
appDialogsManager.loadDialogPhoto(avatarDiv, 0, false, title);
|
||||
appProfileManager.putPhoto(avatarDiv, 0, false, title);
|
||||
}
|
||||
|
||||
avatarDiv.dataset.peerID = message.fromID;
|
||||
|
@ -9,6 +9,7 @@ import { findUpClassName, $rootScope, generatePathData } from "../utils";
|
||||
import appDocsManager from "./appDocsManager";
|
||||
import { wrapPlayer } from "../ckin";
|
||||
import { renderImageFromUrl } from "../../components/misc";
|
||||
import appProfileManager from "./appProfileManager";
|
||||
|
||||
export class AppMediaViewer {
|
||||
private overlaysDiv = document.querySelector('.overlays') as HTMLDivElement;
|
||||
@ -592,7 +593,7 @@ export class AppMediaViewer {
|
||||
this.content.caption.innerHTML = '';
|
||||
}
|
||||
|
||||
appDialogsManager.loadDialogPhoto(this.author.avatarEl, message.fromID);
|
||||
appProfileManager.putPhoto(this.author.avatarEl, message.fromID);
|
||||
|
||||
// ok set
|
||||
|
||||
|
@ -1,16 +1,14 @@
|
||||
import { logger } from "../polyfill";
|
||||
import { putPreloader, formatPhoneNumber } from "../../components/misc";
|
||||
import { formatPhoneNumber } from "../../components/misc";
|
||||
import Scrollable from '../../components/scrollable';
|
||||
import appMessagesManager, { AppMessagesManager } from "./appMessagesManager";
|
||||
import appMessagesManager from "./appMessagesManager";
|
||||
import appDialogsManager from "./appDialogsManager";
|
||||
import { isElementInViewport, numberWithCommas } from "../utils";
|
||||
import { isElementInViewport, numberWithCommas, $rootScope } from "../utils";
|
||||
import appMessagesIDsManager from "./appMessagesIDsManager";
|
||||
import appImManager from "./appImManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
import { appPeersManager } from "../services";
|
||||
import apiManager from "../mtproto/apiManager";
|
||||
|
||||
let testScroll = false;
|
||||
import appPeersManager from './appPeersManager';
|
||||
|
||||
class SearchGroup {
|
||||
container: HTMLDivElement;
|
||||
@ -56,18 +54,6 @@ class AppSidebarLeft {
|
||||
|
||||
private listsContainer: HTMLDivElement = null;
|
||||
|
||||
private chatsArchivedContainer = document.getElementById('chats-archived-container') as HTMLDivElement;
|
||||
private chatsContainer = document.getElementById('chats-container') as HTMLDivElement;
|
||||
private chatsArchivedOffsetIndex = 0;
|
||||
private chatsOffsetIndex = 0;
|
||||
private chatsPreloader: HTMLDivElement;
|
||||
//private chatsLoadCount = 0;
|
||||
//private loadDialogsPromise: Promise<any>;
|
||||
private loadDialogsPromise: ReturnType<AppMessagesManager["getConversations"]>;
|
||||
|
||||
private loadedAll = false;
|
||||
private loadedArchivedAll = false;
|
||||
|
||||
private log = logger('SL');
|
||||
|
||||
private peerID = 0;
|
||||
@ -81,37 +67,16 @@ class AppSidebarLeft {
|
||||
|
||||
private query = '';
|
||||
|
||||
public scroll: Scrollable = null;
|
||||
public scrollArchived: Scrollable = null;
|
||||
public searchGroups: {[group: string]: SearchGroup} = {};
|
||||
|
||||
public searchGroups: {[group: string]: SearchGroup} = {
|
||||
constructor() {
|
||||
this.searchGroups = {
|
||||
contacts: new SearchGroup('Contacts and Chats', 'contacts'),
|
||||
globalContacts: new SearchGroup('Global Search', 'contacts'),
|
||||
globalMessages: new SearchGroup('Global Search', 'messages'),
|
||||
privateMessages: new SearchGroup('Private Search', 'messages')
|
||||
};
|
||||
|
||||
constructor() {
|
||||
this.chatsPreloader = putPreloader(null, true);
|
||||
//this.chatsContainer.append(this.chatsPreloader);
|
||||
|
||||
//this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
|
||||
|
||||
let splitOffset = 1110;
|
||||
|
||||
this.scroll = new Scrollable(this.chatsContainer, 'y', splitOffset, 'CL', appDialogsManager.chatList, 500);
|
||||
this.scroll.setVirtualContainer(appDialogsManager.chatList);
|
||||
this.scroll.onScrolledBottom = this.onChatsScroll.bind(this);
|
||||
appDialogsManager.chatsHidden = this.scroll.hiddenElements;
|
||||
appDialogsManager.chatsVisible = this.scroll.visibleElements;
|
||||
|
||||
this.scrollArchived = new Scrollable(this.chatsArchivedContainer, 'y', splitOffset, 'CLA', appDialogsManager.chatListArchived, 500);
|
||||
this.scrollArchived.setVirtualContainer(appDialogsManager.chatListArchived);
|
||||
this.scrollArchived.onScrolledBottom = this.onChatsArchivedScroll.bind(this);
|
||||
appDialogsManager.chatsArchivedHidden = this.scrollArchived.hiddenElements;
|
||||
appDialogsManager.chatsArchivedVisible = this.scrollArchived.visibleElements;
|
||||
//this.scrollArchived.container.addEventListener('scroll', this.onChatsArchivedScroll.bind(this));
|
||||
|
||||
this.listsContainer = new Scrollable(this.searchContainer).container;
|
||||
for(let i in this.searchGroups) {
|
||||
this.listsContainer.append(this.searchGroups[i].container);
|
||||
@ -126,7 +91,7 @@ class AppSidebarLeft {
|
||||
});
|
||||
|
||||
this.archivedBtn.addEventListener('click', (e) => {
|
||||
this.chatsArchivedContainer.classList.add('active');
|
||||
appDialogsManager.chatsArchivedContainer.classList.add('active');
|
||||
this.toolsBtn.classList.remove('active');
|
||||
this.backBtn.classList.add('active');
|
||||
//this.toolsBtn.classList.remove('tgico-menu', 'btn-menu-toggle');
|
||||
@ -137,15 +102,6 @@ class AppSidebarLeft {
|
||||
apiManager.logOut();
|
||||
});
|
||||
|
||||
if(testScroll) {
|
||||
for(let i = 0; i < 1000; ++i) {
|
||||
let li = document.createElement('li');
|
||||
li.dataset.id = '' + i;
|
||||
li.innerHTML = `<div class="rp"><div class="user-avatar" style="background-color: rgb(166, 149, 231); font-size: 0px;"><img src="#"></div><div class="user-caption"><p><span class="user-title">${i}</span><span><span class="message-status"></span><span class="message-time">18:33</span></span></p><p><span class="user-last-message"><b>-_-_-_-: </b>qweasd</span><span></span></p></div></div>`;
|
||||
this.scroll.append(li);
|
||||
}
|
||||
}
|
||||
|
||||
this.listsContainer.addEventListener('scroll', this.onSidebarScroll.bind(this));
|
||||
|
||||
this.searchInput.addEventListener('focus', (e) => {
|
||||
@ -198,7 +154,7 @@ class AppSidebarLeft {
|
||||
});
|
||||
|
||||
this.backBtn.addEventListener('click', (e) => {
|
||||
this.chatsArchivedContainer.classList.remove('active');
|
||||
appDialogsManager.chatsArchivedContainer.classList.remove('active');
|
||||
this.toolsBtn.classList.add('active');
|
||||
this.backBtn.classList.remove('active');
|
||||
this.searchInput.value = '';
|
||||
@ -211,88 +167,18 @@ class AppSidebarLeft {
|
||||
|
||||
setTimeout(() => {
|
||||
this.onSidebarScroll();
|
||||
this.scroll.onScroll();
|
||||
//this.onChatsScroll();
|
||||
this.onChatsArchivedScroll();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
$rootScope.$on('dialogs_archived_unread', (e: CustomEvent) => {
|
||||
this.archivedCount.innerText = '' + e.detail.count;
|
||||
});
|
||||
|
||||
/* appUsersManager.getTopPeers().then(categories => {
|
||||
this.log('got top categories:', categories);
|
||||
}); */
|
||||
}
|
||||
|
||||
public async loadDialogs(archived = false) {
|
||||
if(testScroll) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.loadDialogsPromise/* || 1 == 1 */) return this.loadDialogsPromise;
|
||||
|
||||
(archived ? this.chatsArchivedContainer : this.chatsContainer).append(this.chatsPreloader);
|
||||
|
||||
//let offset = appMessagesManager.generateDialogIndex();/* appMessagesManager.dialogsNum */;
|
||||
|
||||
let offset = archived ? this.chatsArchivedOffsetIndex : this.chatsOffsetIndex;
|
||||
//let offset = 0;
|
||||
|
||||
let scroll = archived ? this.scrollArchived : this.scroll;
|
||||
scroll.lock();
|
||||
|
||||
try {
|
||||
console.time('getDialogs time');
|
||||
|
||||
let loadCount = 50/*this.chatsLoadCount */;
|
||||
this.loadDialogsPromise = appMessagesManager.getConversations('', offset, loadCount, +archived);
|
||||
|
||||
let result = await this.loadDialogsPromise;
|
||||
|
||||
console.timeEnd('getDialogs time');
|
||||
|
||||
if(result && result.dialogs && result.dialogs.length) {
|
||||
let index = result.dialogs[result.dialogs.length - 1].index;
|
||||
|
||||
if(archived) this.chatsArchivedOffsetIndex = index;
|
||||
else this.chatsOffsetIndex = index;
|
||||
|
||||
result.dialogs.forEach((dialog: any) => {
|
||||
appDialogsManager.addDialog(dialog);
|
||||
});
|
||||
}
|
||||
|
||||
if(!result.dialogs.length || (archived ? this.scrollArchived.length == result.count : this.scroll.length == result.count)) { // loaded all
|
||||
if(archived) this.loadedArchivedAll = true;
|
||||
else this.loadedAll = true;
|
||||
}
|
||||
|
||||
/* if(archived) {
|
||||
let count = result.count;
|
||||
this.archivedCount.innerText = '' + count;
|
||||
} */
|
||||
|
||||
this.log('getDialogs ' + loadCount + ' dialogs by offset:', offset, result, this.scroll.length);
|
||||
this.scroll.onScroll();
|
||||
} catch(err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
|
||||
this.chatsPreloader.remove();
|
||||
this.loadDialogsPromise = undefined;
|
||||
scroll.unlock();
|
||||
}
|
||||
|
||||
public onChatsScroll() {
|
||||
if(this.loadedAll || this.scroll.hiddenElements.down.length > 0 || this.loadDialogsPromise/* || 1 == 1 */) return;
|
||||
|
||||
this.loadDialogs();
|
||||
}
|
||||
|
||||
public onChatsArchivedScroll() {
|
||||
if(this.loadedArchivedAll || this.scrollArchived.hiddenElements.down.length > 0 || this.loadDialogsPromise/* || 1 == 1 */) return;
|
||||
|
||||
this.loadDialogs(true);
|
||||
}
|
||||
|
||||
public onSidebarScroll() {
|
||||
if(!this.query.trim()) return;
|
||||
|
||||
|
@ -22,7 +22,6 @@ export const appChatsManager = AppChatsManager;
|
||||
export const appMessagesIDsManager = AppMessagesIDsManager;
|
||||
export const apiUpdatesManager = ApiUpdatesManager;
|
||||
export const appPhotosManager = AppPhotosManager;
|
||||
export const appDialogsManager = AppDialogsManager;
|
||||
export const appMessagesManager = AppMessagesManager;
|
||||
export const appProfileManager = AppProfileManager;
|
||||
export const appImManager = AppImManager;
|
||||
@ -33,6 +32,7 @@ export const appDocsManager = AppDocsManager;
|
||||
export const appSidebarRight = AppSidebarRight;
|
||||
export const appSidebarLeft = AppSidebarLeft;
|
||||
export const appMediaViewer = AppMediaViewer;
|
||||
export const appDialogsManager = AppDialogsManager;
|
||||
|
||||
(window as any).Services = {
|
||||
appUsersManager,
|
||||
|
@ -61,15 +61,6 @@ export function cancelEvent (event) {
|
||||
return false
|
||||
}
|
||||
|
||||
export function onCtrlEnter (textarea, cb) {
|
||||
$(textarea).on('keydown', function (e) {
|
||||
if (e.keyCode == 13 && (e.ctrlKey || e.metaKey)) {
|
||||
cb()
|
||||
return cancelEvent(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function setFieldSelection (field, from, to) {
|
||||
field = $(field)[0]
|
||||
try {
|
||||
@ -307,6 +298,7 @@ export const $rootScope = {
|
||||
},
|
||||
|
||||
selectedPeerID: 0,
|
||||
myID: 0,
|
||||
idle: {
|
||||
isIDLE: false
|
||||
}
|
||||
|
28
src/pages/page.ts
Normal file
28
src/pages/page.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import pagesManager from "./pagesManager";
|
||||
|
||||
export default class Page {
|
||||
public pageEl: HTMLDivElement;
|
||||
private installed = false;
|
||||
|
||||
constructor(className: string, public isAuthPage: boolean, private onFirstMount?: (...args: any[]) => void, private onMount?: (...args: any[]) => void) {
|
||||
this.pageEl = document.body.getElementsByClassName(className)[0] as HTMLDivElement;
|
||||
}
|
||||
|
||||
public mount(...args: any[]) {
|
||||
//this.pageEl.style.display = '';
|
||||
|
||||
if(this.onMount) {
|
||||
this.onMount(...args);
|
||||
}
|
||||
|
||||
if(!this.installed) {
|
||||
if(this.onFirstMount) {
|
||||
this.onFirstMount(...args);
|
||||
}
|
||||
|
||||
this.installed = true;
|
||||
}
|
||||
|
||||
pagesManager.setPage(this);
|
||||
}
|
||||
}
|
@ -5,8 +5,8 @@ import pagePassword from './pagePassword';
|
||||
import CryptoWorker from '../lib/crypto/cryptoworker';
|
||||
import LottieLoader from '../lib/lottieLoader';
|
||||
import apiManager from '../lib/mtproto/apiManager';
|
||||
import Page from './page';
|
||||
|
||||
let installed = false;
|
||||
let authCode: {
|
||||
_: string, // 'auth.sentCode'
|
||||
pFlags: any, // {}
|
||||
@ -21,37 +21,10 @@ let authCode: {
|
||||
|
||||
const EDITONSAMEPAGE = false;
|
||||
|
||||
export default async(_authCode: typeof authCode) => {
|
||||
authCode = _authCode;
|
||||
|
||||
//let LottieLoader = (await import('../lib/lottieLoader')).default;
|
||||
|
||||
let pageElement = document.body.getElementsByClassName('page-authCode')[0] as HTMLDivElement;
|
||||
pageElement.style.display = '';
|
||||
|
||||
let headerElement = pageElement.getElementsByClassName('phone')[0] as HTMLHeadElement;
|
||||
headerElement.innerText = authCode.phone_number;
|
||||
|
||||
let sentTypeElement = pageElement.getElementsByClassName('sent-type')[0] as HTMLParagraphElement;
|
||||
|
||||
switch(authCode.type._) {
|
||||
case 'auth.sentCodeTypeSms':
|
||||
sentTypeElement.innerHTML = 'We have sent you an SMS<br>with the code.';
|
||||
break;
|
||||
case 'auth.sentCodeTypeApp':
|
||||
sentTypeElement.innerHTML = 'We have sent you a message in Telegram<br>with the code.';
|
||||
break;
|
||||
case 'auth.sentCodeTypeCall':
|
||||
sentTypeElement.innerHTML = 'We will call you and voice<br>the code.';
|
||||
break;
|
||||
default:
|
||||
sentTypeElement.innerHTML = `Please check everything<br>for a code (type: ${authCode.type._})`;
|
||||
break;
|
||||
}
|
||||
|
||||
if(installed) return;
|
||||
installed = true;
|
||||
let headerElement: HTMLHeadElement = null;
|
||||
let sentTypeElement: HTMLParagraphElement = null;
|
||||
|
||||
let onFirstMount = () => {
|
||||
let needFrame = 0, lastLength = 0;
|
||||
let animation: /* AnimationItem */any = undefined;
|
||||
|
||||
@ -63,7 +36,7 @@ export default async(_authCode: typeof authCode) => {
|
||||
let str = await CryptoWorker.gzipUncompress<string>(data, true);
|
||||
|
||||
animation = await LottieLoader.loadAnimation({
|
||||
container: document.body.querySelector('.page-authCode .auth-image'),
|
||||
container: page.pageEl.querySelector('.auth-image'),
|
||||
renderer: 'svg',
|
||||
loop: false,
|
||||
autoplay: false,
|
||||
@ -85,9 +58,9 @@ export default async(_authCode: typeof authCode) => {
|
||||
});
|
||||
});
|
||||
|
||||
const codeInput = document.getElementById('code') as HTMLInputElement;
|
||||
const codeInput = page.pageEl.querySelector('#code') as HTMLInputElement;
|
||||
const codeInputLabel = codeInput.nextElementSibling as HTMLLabelElement;
|
||||
const editButton = document.querySelector('.phone-edit') as HTMLElement;
|
||||
const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement;
|
||||
|
||||
if(EDITONSAMEPAGE) {
|
||||
let editable = false;
|
||||
@ -162,8 +135,7 @@ export default async(_authCode: typeof authCode) => {
|
||||
});
|
||||
} else {
|
||||
editButton.addEventListener('click', function() {
|
||||
pageElement.style.display = 'none';
|
||||
return pageSignIn();
|
||||
return pageSignIn.mount();
|
||||
});
|
||||
}
|
||||
|
||||
@ -188,15 +160,13 @@ export default async(_authCode: typeof authCode) => {
|
||||
id: response.user.id
|
||||
});
|
||||
|
||||
pageElement.style.display = 'none';
|
||||
pageIm();
|
||||
pageIm.mount();
|
||||
if(animation) animation.destroy();
|
||||
break;
|
||||
case 'auth.authorizationSignUpRequired':
|
||||
console.log('Registration needed!');
|
||||
|
||||
pageElement.style.display = 'none';
|
||||
pageSignUp({
|
||||
pageSignUp.mount({
|
||||
'phone_number': authCode.phone_number,
|
||||
'phone_code_hash': authCode.phone_code_hash
|
||||
});
|
||||
@ -214,9 +184,8 @@ export default async(_authCode: typeof authCode) => {
|
||||
case 'SESSION_PASSWORD_NEEDED':
|
||||
console.warn('pageAuthCode: SESSION_PASSWORD_NEEDED');
|
||||
err.handled = true;
|
||||
pageElement.style.display = 'none';
|
||||
if(animation) animation.destroy();
|
||||
pagePassword();
|
||||
pagePassword.mount();
|
||||
break;
|
||||
case 'PHONE_CODE_EMPTY':
|
||||
case 'PHONE_CODE_INVALID':
|
||||
@ -259,7 +228,7 @@ export default async(_authCode: typeof authCode) => {
|
||||
|
||||
let direction = needFrame > frame ? -1 : 1;
|
||||
//console.log('keydown', length, frame, direction);
|
||||
// @ts-ignore
|
||||
|
||||
animation.setDirection(direction);
|
||||
if(needFrame != 0 && frame == 0) {
|
||||
animation.setSpeed(7);
|
||||
@ -274,3 +243,32 @@ export default async(_authCode: typeof authCode) => {
|
||||
//animation.goToAndStop(length / max * );
|
||||
});
|
||||
};
|
||||
|
||||
const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof authCode) => {
|
||||
authCode = _authCode;
|
||||
|
||||
if(!headerElement) {
|
||||
headerElement = page.pageEl.getElementsByClassName('phone')[0] as HTMLHeadElement;
|
||||
sentTypeElement = page.pageEl.getElementsByClassName('sent-type')[0] as HTMLParagraphElement;
|
||||
}
|
||||
|
||||
//let LottieLoader = (await import('../lib/lottieLoader')).default;
|
||||
|
||||
headerElement.innerText = authCode.phone_number;
|
||||
switch(authCode.type._) {
|
||||
case 'auth.sentCodeTypeSms':
|
||||
sentTypeElement.innerHTML = 'We have sent you an SMS<br>with the code.';
|
||||
break;
|
||||
case 'auth.sentCodeTypeApp':
|
||||
sentTypeElement.innerHTML = 'We have sent you a message in Telegram<br>with the code.';
|
||||
break;
|
||||
case 'auth.sentCodeTypeCall':
|
||||
sentTypeElement.innerHTML = 'We will call you and voice<br>the code.';
|
||||
break;
|
||||
default:
|
||||
sentTypeElement.innerHTML = `Please check everything<br>for a code (type: ${authCode.type._})`;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
export default page;
|
111
src/pages/pageIm.ts
Normal file
111
src/pages/pageIm.ts
Normal file
@ -0,0 +1,111 @@
|
||||
import { openBtnMenu, ripple } from "../components/misc";
|
||||
//import {stackBlurImage} from '../lib/StackBlur';
|
||||
import Page from "./page";
|
||||
//import appImManager from '../lib/appManagers/appImManager';
|
||||
|
||||
let onFirstMount = () => import('../lib/appManagers/appImManager').then(() => {//import('../lib/services').then(services => {
|
||||
//console.log('included services', services);
|
||||
|
||||
//export default () => {
|
||||
|
||||
|
||||
/*
|
||||
loadDialogs().then(result => {
|
||||
//appImManager.setScroll(chatScroll);
|
||||
});
|
||||
return;
|
||||
*/
|
||||
|
||||
|
||||
/* function placeCaretAfterNode(node: HTMLElement) {
|
||||
if (typeof window.getSelection != "undefined") {
|
||||
var range = document.createRange();
|
||||
range.setStartAfter(node);
|
||||
range.collapse(true);
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
}
|
||||
|
||||
messageInput.onclick = (e) => {
|
||||
let target = e.target as HTMLElement;
|
||||
if(target.classList.contains('emoji-inner')) {
|
||||
placeCaretAfterNode(target.parentElement);
|
||||
} else if(target.classList.contains('emoji-sizer')) {
|
||||
placeCaretAfterNode(target);
|
||||
}
|
||||
console.log('lol', target);
|
||||
}; */
|
||||
|
||||
/* window.addEventListener('click', function(this, e) {
|
||||
// @ts-ignore
|
||||
let isInput = e.target.tagName == 'INPUT';
|
||||
if(!isInput && !window.getSelection().toString()) {
|
||||
console.log('click');
|
||||
messageInput.focus();
|
||||
}
|
||||
}); */
|
||||
|
||||
/* fetch('assets/img/camomile.jpg')
|
||||
.then(res => res.blob())
|
||||
.then(blob => {
|
||||
let img = new Image();
|
||||
let url = URL.createObjectURL(blob);
|
||||
img.src = url;
|
||||
img.onload = () => {
|
||||
let id = 'chat-background-canvas';
|
||||
var canvas = document.getElementById(id) as HTMLCanvasElement;
|
||||
//URL.revokeObjectURL(url);
|
||||
|
||||
let elements = ['.chat-container'].map(selector => {
|
||||
return document.querySelector(selector) as HTMLDivElement;
|
||||
});
|
||||
|
||||
stackBlurImage(img, id, 15, 0);
|
||||
|
||||
canvas.toBlob(blob => {
|
||||
//let dataUrl = canvas.toDataURL('image/jpeg', 1);
|
||||
let dataUrl = URL.createObjectURL(blob);
|
||||
|
||||
elements.forEach(el => {
|
||||
el.style.backgroundImage = 'url(' + dataUrl + ')';
|
||||
});
|
||||
}, 'image/jpeg', 1);
|
||||
};
|
||||
}); */
|
||||
|
||||
/* toggleEmoticons.onclick = (e) => {
|
||||
if(!emoticonsDropdown) {
|
||||
emoticonsDropdown = initEmoticonsDropdown(pageEl, appImManager,
|
||||
appMessagesManager, messageInput, toggleEmoticons);
|
||||
} else {
|
||||
emoticonsDropdown.classList.toggle('active');
|
||||
}
|
||||
|
||||
toggleEmoticons.classList.toggle('active');
|
||||
}; */
|
||||
|
||||
(Array.from(document.getElementsByClassName('rp')) as HTMLElement[]).forEach(el => ripple(el));
|
||||
|
||||
Array.from(document.getElementsByClassName('btn-menu-toggle')).forEach((el) => {
|
||||
el.addEventListener('click', (e) => {
|
||||
//console.log('click pageIm');
|
||||
if(!el.classList.contains('btn-menu-toggle')) return false;
|
||||
|
||||
//window.removeEventListener('mousemove', onMouseMove);
|
||||
let openedMenu = el.querySelector('.btn-menu') as HTMLDivElement;
|
||||
e.cancelBubble = true;
|
||||
|
||||
if(el.classList.contains('menu-open')) {
|
||||
el.classList.remove('menu-open');
|
||||
openedMenu.classList.remove('active');
|
||||
} else {
|
||||
openBtnMenu(openedMenu);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const page = new Page('page-chats', false, onFirstMount);
|
||||
export default page;
|
@ -1,25 +1,17 @@
|
||||
import pageIm from './pageIm';
|
||||
import CryptoWorker from '../lib/crypto/cryptoworker';
|
||||
import { putPreloader } from './misc';
|
||||
import { putPreloader } from '../components/misc';
|
||||
|
||||
import LottieLoader from '../lib/lottieLoader';
|
||||
import passwordManager from '../lib/mtproto/passwordManager';
|
||||
import apiManager from '../lib/mtproto/apiManager';
|
||||
import Page from './page';
|
||||
|
||||
let installed = false;
|
||||
|
||||
export default async() => {
|
||||
//let LottieLoader = (await import('../lib/lottieLoader')).default;
|
||||
|
||||
if(installed) return;
|
||||
installed = true;
|
||||
|
||||
let onFirstMount = () => {
|
||||
let needFrame = 0;
|
||||
let animation: /* AnimationItem */any = undefined;
|
||||
|
||||
let passwordVisible = false;
|
||||
let pageElement = document.body.getElementsByClassName('page-password')[0] as HTMLDivElement;
|
||||
pageElement.style.display = '';
|
||||
|
||||
fetch('assets/img/TwoFactorSetupMonkeyClose.tgs')
|
||||
.then(res => res.arrayBuffer())
|
||||
@ -27,7 +19,7 @@ export default async() => {
|
||||
let str = await CryptoWorker.gzipUncompress<string>(data, true);
|
||||
|
||||
animation = await LottieLoader.loadAnimation({
|
||||
container: pageElement.querySelector('.auth-image'),
|
||||
container: page.pageEl.querySelector('.auth-image'),
|
||||
renderer: 'svg',
|
||||
loop: false,
|
||||
autoplay: false,
|
||||
@ -52,10 +44,10 @@ export default async() => {
|
||||
animation.play();
|
||||
});
|
||||
|
||||
const btnNext = pageElement.querySelector('button') as HTMLButtonElement;
|
||||
const btnNext = page.pageEl.querySelector('button') as HTMLButtonElement;
|
||||
const passwordInput = document.getElementById('password') as HTMLInputElement;
|
||||
//const passwordInputLabel = passwordInput.nextElementSibling as HTMLLabelElement;
|
||||
const toggleVisible = pageElement.querySelector('.toggle-visible') as HTMLSpanElement;
|
||||
const toggleVisible = page.pageEl.querySelector('.toggle-visible') as HTMLSpanElement;
|
||||
|
||||
let handleError = (err: any) => {
|
||||
btnNext.removeAttribute('disabled');
|
||||
@ -109,8 +101,7 @@ export default async() => {
|
||||
id: response.user.id
|
||||
});
|
||||
|
||||
pageElement.style.display = 'none';
|
||||
pageIm();
|
||||
pageIm.mount();
|
||||
if(animation) animation.destroy();
|
||||
break;
|
||||
default:
|
||||
@ -134,3 +125,7 @@ export default async() => {
|
||||
|
||||
}); */
|
||||
};
|
||||
|
||||
const page = new Page('page-password', true, onFirstMount);
|
||||
|
||||
export default page;
|
@ -1,13 +1,12 @@
|
||||
import { putPreloader, formatPhoneNumber } from "./misc";
|
||||
import Scrollable from './scrollable';
|
||||
import { putPreloader, formatPhoneNumber } from "../components/misc";
|
||||
import Scrollable from '../components/scrollable';
|
||||
import {RichTextProcessor} from '../lib/richtextprocessor';
|
||||
import * as Config from '../lib/config';
|
||||
|
||||
import { findUpTag } from "../lib/utils";
|
||||
import pageAuthCode from "./pageAuthCode";
|
||||
import apiManager from "../lib/mtproto/apiManager";
|
||||
|
||||
let installed = false;
|
||||
import Page from "./page";
|
||||
|
||||
type Country = {
|
||||
name: string,
|
||||
@ -19,30 +18,15 @@ type Country = {
|
||||
};
|
||||
|
||||
//import _countries from '../countries_pretty.json';
|
||||
let btnNext: HTMLButtonElement = null;
|
||||
|
||||
export default () => {
|
||||
//export default () => import('../countries.json').then(_countries => {
|
||||
//let pageAuthCode = await import('./pageAuthCode');
|
||||
//Array.from(document.querySelectorAll('body > .whole:not(.page-authCode)')).forEach(div => div.style.display = 'none');
|
||||
const pageEl = document.body.getElementsByClassName('page-sign')[0] as HTMLDivElement;
|
||||
pageEl.style.display = '';
|
||||
|
||||
let btnNext = pageEl.querySelector('button');
|
||||
|
||||
if(installed) {
|
||||
btnNext.textContent = 'NEXT';
|
||||
btnNext.removeAttribute('disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
installed = true;
|
||||
|
||||
let onFirstMount = () => {
|
||||
//const countries: Country[] = _countries.default.filter(c => c.emoji);
|
||||
const countries: Country[] = Config.Countries.filter(c => c.emoji).sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
let lastCountrySelected = '';
|
||||
|
||||
var selectCountryCode = pageEl.querySelector('input[name="countryCode"]')! as HTMLInputElement;
|
||||
var selectCountryCode = page.pageEl.querySelector('input[name="countryCode"]')! as HTMLInputElement;
|
||||
var parent = selectCountryCode.parentElement;
|
||||
|
||||
var wrapper = document.createElement('div');
|
||||
@ -148,7 +132,7 @@ export default () => {
|
||||
}
|
||||
});
|
||||
|
||||
let arrowDown = pageEl.querySelector('.arrow-down') as HTMLSpanElement;
|
||||
let arrowDown = page.pageEl.querySelector('.arrow-down') as HTMLSpanElement;
|
||||
arrowDown.addEventListener('mousedown', function(this: typeof arrowDown, e) {
|
||||
e.cancelBubble = true;
|
||||
e.preventDefault();
|
||||
@ -158,7 +142,7 @@ export default () => {
|
||||
|
||||
let sortedCountries = countries.slice().sort((a, b) => b.phoneCode.length - a.phoneCode.length);
|
||||
|
||||
let telEl = pageEl.querySelector('input[name="phone"]') as HTMLInputElement;
|
||||
let telEl = page.pageEl.querySelector('input[name="phone"]') as HTMLInputElement;
|
||||
telEl.addEventListener('input', function(this: typeof telEl, e) {
|
||||
this.classList.remove('error');
|
||||
|
||||
@ -217,10 +201,7 @@ export default () => {
|
||||
}).then((code: any) => {
|
||||
console.log('got code', code);
|
||||
|
||||
pageEl.style.display = 'none';
|
||||
|
||||
// @ts-ignore
|
||||
pageAuthCode(Object.assign(code, {phone_number: phone_number}));
|
||||
pageAuthCode.mount(Object.assign(code, {phone_number: phone_number}));
|
||||
}).catch(err => {
|
||||
this.removeAttribute('disabled');
|
||||
|
||||
@ -230,6 +211,7 @@ export default () => {
|
||||
telEl.classList.add('error');
|
||||
break;
|
||||
default:
|
||||
console.error('auth.sendCode error:', err);
|
||||
this.innerText = err.type;
|
||||
break;
|
||||
}
|
||||
@ -259,5 +241,15 @@ export default () => {
|
||||
};
|
||||
|
||||
tryAgain();
|
||||
|
||||
};
|
||||
|
||||
const page = new Page('page-sign', true, onFirstMount, () => {
|
||||
if(!btnNext) {
|
||||
btnNext = page.pageEl.querySelector('button');
|
||||
}
|
||||
|
||||
btnNext.textContent = 'NEXT';
|
||||
btnNext.removeAttribute('disabled');
|
||||
});
|
||||
|
||||
export default page;
|
@ -1,24 +1,17 @@
|
||||
import {putPreloader} from './misc';
|
||||
import {putPreloader} from '../components/misc';
|
||||
import resizeableImage from '../lib/cropper';
|
||||
import pageIm from './pageIm';
|
||||
import apiManager from '../lib/mtproto/apiManager';
|
||||
import apiFileManager from '../lib/mtproto/apiFileManager';
|
||||
import Page from './page';
|
||||
|
||||
let installed = false;
|
||||
let authCode: {
|
||||
'phone_number': string,
|
||||
'phone_code_hash': string
|
||||
} = null;
|
||||
|
||||
import resizeableImage from '../lib/cropper';
|
||||
import pageIm from './pageIm';
|
||||
import apiManager from '../lib/mtproto/apiManager';
|
||||
import apiFileManager from '../lib/mtproto/apiFileManager';
|
||||
|
||||
export default (_authCode: typeof authCode) => {
|
||||
authCode = _authCode;
|
||||
if(installed) return;
|
||||
installed = true;
|
||||
|
||||
let pageElement = document.body.getElementsByClassName('page-signUp')[0] as HTMLDivElement;
|
||||
pageElement.style.display = '';
|
||||
|
||||
let onFirstMount = () => {
|
||||
const pageElement = page.pageEl;
|
||||
const avatarInput = document.getElementById('avatar-input') as HTMLInputElement;
|
||||
const avatarPopup = pageElement.getElementsByClassName('popup-avatar')[0];
|
||||
const avatarPreview = pageElement.querySelector('#canvas-avatar') as HTMLCanvasElement;
|
||||
@ -170,11 +163,9 @@ export default (_authCode: typeof authCode) => {
|
||||
});
|
||||
|
||||
sendAvatar().then(() => {
|
||||
pageElement.style.display = 'none';
|
||||
pageIm();
|
||||
pageIm.mount();
|
||||
}, () => {
|
||||
pageElement.style.display = 'none';
|
||||
pageIm();
|
||||
pageIm.mount();
|
||||
});
|
||||
|
||||
break;
|
||||
@ -196,3 +187,9 @@ export default (_authCode: typeof authCode) => {
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const page = new Page('page-signUp', true, onFirstMount, (_authCode: typeof authCode) => {
|
||||
authCode = _authCode;
|
||||
});
|
||||
|
||||
export default page;
|
37
src/pages/pagesManager.ts
Normal file
37
src/pages/pagesManager.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import Page from "./page";
|
||||
import { whichChild } from "../lib/utils";
|
||||
import { horizontalMenu } from "../components/misc";
|
||||
|
||||
class PagesManager {
|
||||
private pageID = -1;
|
||||
|
||||
private selectTab: ReturnType<typeof horizontalMenu>;
|
||||
public pagesDiv: HTMLDivElement;
|
||||
|
||||
constructor() {
|
||||
this.pagesDiv = document.getElementById('auth-pages') as HTMLDivElement;
|
||||
this.selectTab = horizontalMenu(null, this.pagesDiv.firstElementChild as HTMLDivElement, null, null, 420);
|
||||
}
|
||||
|
||||
public setPage(page: Page) {
|
||||
if(page.isAuthPage) {
|
||||
this.pagesDiv.style.display = '';
|
||||
|
||||
let id = whichChild(page.pageEl);
|
||||
if(this.pageID == id) return;
|
||||
|
||||
this.selectTab(id);
|
||||
|
||||
this.pageID = id;
|
||||
} else {
|
||||
this.pagesDiv.style.display = 'none';
|
||||
page.pageEl.style.display = '';
|
||||
|
||||
this.pageID = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const pagesManager = new PagesManager();
|
||||
(window as any).pagesManager = pagesManager;
|
||||
export default pagesManager;
|
@ -62,7 +62,7 @@
|
||||
}
|
||||
|
||||
&.active {
|
||||
margin-top: 1px;
|
||||
//margin-top: 1px;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
color: #707579;
|
||||
|
@ -133,8 +133,8 @@ input {
|
||||
|
||||
.btn-icon {
|
||||
text-align: center;
|
||||
font-size: 1.65rem;
|
||||
line-height: 1.65rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.5rem;
|
||||
border-radius: 50%;
|
||||
-webkit-transition: background-color .15s ease-out;
|
||||
transition: background-color .15s ease-out;
|
||||
@ -496,6 +496,32 @@ input {
|
||||
}
|
||||
}
|
||||
|
||||
#auth-pages {
|
||||
max-width: 720px; // 360 + 360 / 2
|
||||
overflow: hidden;
|
||||
|
||||
.tabs-container {
|
||||
&.animated {
|
||||
transition: .42s transform;
|
||||
}
|
||||
|
||||
> div {
|
||||
justify-content: center;
|
||||
/* &.active {
|
||||
flex-direction: row;
|
||||
} */
|
||||
|
||||
> div {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
/* display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center; */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-sign {
|
||||
.auth-image {
|
||||
width: 160px;
|
||||
@ -1302,7 +1328,7 @@ div.scrollable::-webkit-scrollbar-thumb {
|
||||
max-height: 100%;
|
||||
//position: relative;
|
||||
|
||||
will-change: transform;
|
||||
//will-change: transform;
|
||||
transform: translateZ(0);
|
||||
-webkit-transform: translateZ(0);
|
||||
|
||||
@ -1412,12 +1438,13 @@ div.scrollable::-webkit-scrollbar-thumb {
|
||||
|
||||
.tabs-container {
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
/* overflow: hidden; */
|
||||
overflow-x: hidden;
|
||||
|
||||
&.animated {
|
||||
transition: .2s margin-left;
|
||||
transition: .3s transform;
|
||||
}
|
||||
|
||||
> div {
|
||||
|
Loading…
x
Reference in New Issue
Block a user