check that (new virtual scroll)
This commit is contained in:
parent
107ab79c92
commit
8873c2d3ec
15
package-lock.json
generated
15
package-lock.json
generated
@ -4004,6 +4004,15 @@
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fastdom": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/fastdom/-/fastdom-1.0.9.tgz",
|
||||
"integrity": "sha512-SSp4fbVzu8JkkG01NUX+0iOwe9M5PN3MGIQ84txLf4TkkJG4q30khkzumKgi4hUqO1+jX6wLHfnCPoZ6eSZ6Tg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"strictdom": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"faye-websocket": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
|
||||
@ -12823,6 +12832,12 @@
|
||||
"integrity": "sha512-IpXeZ67YxcsrfZHe3yg/IyZ5KPfRSn1teDy5mRX2e8M6K410NcJNcR+SFQ2Z92DO36VBUArQP4Vy3Qu33MwIOQ==",
|
||||
"dev": true
|
||||
},
|
||||
"strictdom": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strictdom/-/strictdom-1.0.1.tgz",
|
||||
"integrity": "sha1-GJ3pFkn3PUTVm4Qy76aO+dJllGA=",
|
||||
"dev": true
|
||||
},
|
||||
"string-length": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
|
||||
|
@ -35,6 +35,7 @@
|
||||
"babel-jest": "^24.9.0",
|
||||
"compression-webpack-plugin": "^3.1.0",
|
||||
"css-loader": "^3.2.0",
|
||||
"fastdom": "^1.0.9",
|
||||
"file-loader": "^4.3.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"install": "^0.13.0",
|
||||
|
@ -1,8 +1,6 @@
|
||||
//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 => {
|
||||
|
@ -1,4 +1,19 @@
|
||||
import { isElementInViewport, isScrolledIntoView, cancelEvent } from "../lib/utils";
|
||||
import { cancelEvent } from "../lib/utils";
|
||||
|
||||
//import {measure} from 'fastdom/fastdom.min';
|
||||
import FastDom from 'fastdom';
|
||||
import 'fastdom/src/fastdom-strict'; // exclude in production
|
||||
import FastDomPromised from 'fastdom/extensions/fastdom-promised';
|
||||
|
||||
//const fastdom = FastDom.extend(FastDomPromised);
|
||||
const fastdom = ((window as any).fastdom as typeof FastDom).extend(FastDomPromised);
|
||||
|
||||
(window as any).fastdom.strict(false);
|
||||
|
||||
setTimeout(() => {
|
||||
//(window as any).fastdom.strict(true);
|
||||
}, 5e3);
|
||||
|
||||
|
||||
export default class Scrollable {
|
||||
public container: HTMLDivElement;
|
||||
@ -27,7 +42,6 @@ export default class Scrollable {
|
||||
public paddingBottomDiv: HTMLDivElement;
|
||||
|
||||
public splitUp: HTMLElement;
|
||||
public splitOffset = 0;
|
||||
|
||||
public onAddedBottom: () => void = null;
|
||||
|
||||
@ -37,8 +51,10 @@ export default class Scrollable {
|
||||
public isBottomIntersecting: boolean;
|
||||
|
||||
public splitObserver: IntersectionObserver;
|
||||
public splitMeasure: Promise<any> = null;
|
||||
public splitMutate: Promise<any> = null;
|
||||
|
||||
constructor(public el: HTMLDivElement, x = false, y = true) {
|
||||
constructor(public el: HTMLDivElement, x = false, y = true, public splitOffset = 300) {
|
||||
this.container = document.createElement('div');
|
||||
this.container.classList.add('scrollable');
|
||||
|
||||
@ -47,7 +63,7 @@ export default class Scrollable {
|
||||
this.topObserver = new IntersectionObserver(entries => {
|
||||
let entry = entries[0];
|
||||
|
||||
// console.log('top intersection:', entries, this.isTopIntersecting, entry.isIntersecting, entry.intersectionRatio > 0);
|
||||
console.log('top intersection:', entries, this.isTopIntersecting, entry.isIntersecting, entry.intersectionRatio > 0);
|
||||
if(this.isTopIntersecting = entry.isIntersecting) {
|
||||
this.onTopIntersection(entry);
|
||||
}
|
||||
@ -57,7 +73,7 @@ export default class Scrollable {
|
||||
this.bottomObserver = new IntersectionObserver(entries => {
|
||||
let entry = entries[0];
|
||||
|
||||
// console.log('bottom intersection:', entries, this.isBottomIntersecting, entry.isIntersecting, entry.intersectionRatio > 0);
|
||||
console.log('bottom intersection:', entries, this.isBottomIntersecting, entry.isIntersecting, entry.intersectionRatio > 0);
|
||||
if(this.isBottomIntersecting = entry.isIntersecting) {
|
||||
this.onBottomIntersection(entry);
|
||||
|
||||
@ -66,48 +82,89 @@ export default class Scrollable {
|
||||
}, {threshold: arr});
|
||||
|
||||
this.splitObserver = new IntersectionObserver(entries => {
|
||||
//console.log('splitObserver', entries);
|
||||
|
||||
for(let entry of entries) {
|
||||
console.log('splitObserver', entries);
|
||||
for(let entry of entries) { // there may be duplicates (1st - not intersecting, 2nd - intersecting)
|
||||
//console.log('onscroll entry', entry.target, entry.isIntersecting, entry);
|
||||
if(!entry.isIntersecting && entry.target.parentElement) {
|
||||
if(!entry.isIntersecting && entry.target.parentElement && entry.rootBounds) {
|
||||
let child = entry.target;
|
||||
//console.log('onscroll entry', entry.boundingClientRect, child, entry);
|
||||
|
||||
let isTop = (entry.boundingClientRect.top + this.splitOffset) <= 0;
|
||||
let isTop = entry.boundingClientRect.top <= 0;
|
||||
let isBottom = entry.rootBounds.height <= entry.boundingClientRect.top;
|
||||
|
||||
let needHeight = this.splitOffset;
|
||||
//console.log('will call measure');
|
||||
if(isTop) {
|
||||
let sliced: Element[] = [child];
|
||||
this.onBottomIntersection(entry);
|
||||
|
||||
while(child.previousElementSibling) {
|
||||
sliced.push(child = child.previousElementSibling);
|
||||
}
|
||||
if(this.splitMeasure) fastdom.clear(this.splitMeasure);
|
||||
this.splitMeasure = fastdom.measure(() => {
|
||||
let sliced: {element: Element, height: number}[] = [/* child */];
|
||||
|
||||
sliced.reverse();
|
||||
sliced.forEach(child => {
|
||||
let height = child.scrollHeight;
|
||||
this.paddings.up += height;
|
||||
this.hiddenElements.up.push({element: child, height});
|
||||
child.parentElement.removeChild(child);
|
||||
this.paddingTopDiv.style.height = this.paddings.up + 'px';
|
||||
do {
|
||||
if(needHeight > 0) {
|
||||
needHeight -= child.scrollHeight;
|
||||
} else {
|
||||
sliced.push({element: child, height: child.scrollHeight});
|
||||
}
|
||||
} while(child = child.previousElementSibling);
|
||||
return sliced;
|
||||
});
|
||||
|
||||
this.splitMeasure.then(sliced => {
|
||||
if(this.splitMutate) fastdom.clear(this.splitMutate);
|
||||
this.splitMutate = fastdom.mutate(() => {
|
||||
let length = sliced.length;
|
||||
for(let i = length - 1; i >= 0; --i) {
|
||||
let {element, height} = sliced[i];
|
||||
|
||||
if(!this.splitUp.contains(element)) continue;
|
||||
|
||||
this.paddings.up += height;
|
||||
this.hiddenElements.up.push(sliced[i]);
|
||||
this.splitUp.removeChild(element);
|
||||
//element.parentElement.removeChild(element);
|
||||
}
|
||||
|
||||
this.paddingTopDiv.style.height = this.paddings.up + 'px';
|
||||
});
|
||||
});
|
||||
|
||||
//console.log('onscroll sliced up', sliced);
|
||||
} else if(isBottom) {
|
||||
let sliced: Element[] = [child];
|
||||
this.onTopIntersection(entry);
|
||||
|
||||
while(child.nextElementSibling) {
|
||||
sliced.push(child = child.nextElementSibling);
|
||||
}
|
||||
if(this.splitMeasure) fastdom.clear(this.splitMeasure);
|
||||
this.splitMeasure = fastdom.measure(() => {
|
||||
let sliced: {element: Element, height: number}[] = [/* child */];
|
||||
|
||||
sliced.reverse();
|
||||
sliced.forEach(child => {
|
||||
let height = child.scrollHeight;
|
||||
this.paddings.down += height;
|
||||
this.hiddenElements.down.unshift({element: child, height});
|
||||
child.parentElement.removeChild(child);
|
||||
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
|
||||
do {
|
||||
if(needHeight > 0) {
|
||||
needHeight -= child.scrollHeight;
|
||||
} else {
|
||||
sliced.push({element: child, height: child.scrollHeight});
|
||||
}
|
||||
} while(child = child.nextElementSibling);
|
||||
return sliced;
|
||||
});
|
||||
|
||||
this.splitMeasure.then(sliced => {
|
||||
if(this.splitMutate) fastdom.clear(this.splitMutate);
|
||||
this.splitMutate = fastdom.mutate(() => {
|
||||
let length = sliced.length;
|
||||
for(let i = length - 1; i >= 0; --i) {
|
||||
let {element, height} = sliced[i];
|
||||
|
||||
if(!this.splitUp.contains(element)) continue;
|
||||
|
||||
this.paddings.down += height;
|
||||
this.hiddenElements.down.unshift(sliced[i]);
|
||||
this.splitUp.removeChild(element);
|
||||
//element.parentElement.removeChild(element);
|
||||
}
|
||||
|
||||
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
|
||||
});
|
||||
});
|
||||
|
||||
//console.log('onscroll sliced down', sliced);
|
||||
@ -159,6 +216,7 @@ export default class Scrollable {
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.type] = '30px';
|
||||
|
||||
// mouse scroll
|
||||
let onMouseMove = (e: MouseEvent) => {
|
||||
let rect = this.thumb.getBoundingClientRect();
|
||||
|
||||
@ -194,101 +252,104 @@ export default class Scrollable {
|
||||
|
||||
this.container.addEventListener('scroll', this.onScroll.bind(this));
|
||||
|
||||
//this.container.append(this.paddingTopDiv);
|
||||
Array.from(el.children).forEach(c => this.container.append(c));
|
||||
//this.container.append(this.paddingBottomDiv);
|
||||
|
||||
el.append(this.container);//container.append(el);
|
||||
el.append(this.container);
|
||||
this.container.parentElement.append(this.thumb);
|
||||
this.resize();
|
||||
}
|
||||
|
||||
public resize() {
|
||||
console.time('scroll resize');
|
||||
// @ts-ignore
|
||||
this.scrollSize = this.container[this.scrollType];
|
||||
public async resize() {
|
||||
//console.time('scroll resize');
|
||||
|
||||
await fastdom.measure(() => {
|
||||
// @ts-ignore
|
||||
this.scrollSize = this.container[this.scrollType];
|
||||
|
||||
let rect = this.container.getBoundingClientRect();
|
||||
|
||||
// @ts-ignore
|
||||
this.size = rect[this.type];
|
||||
});
|
||||
|
||||
let rect = this.container.getBoundingClientRect();
|
||||
|
||||
// @ts-ignore
|
||||
this.size = rect[this.type];
|
||||
|
||||
if(!this.size || this.size == this.scrollSize) {
|
||||
this.thumbSize = 0;
|
||||
await fastdom.mutate(() => {
|
||||
if(!this.size || this.size == this.scrollSize) {
|
||||
this.thumbSize = 0;
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.type] = this.thumbSize + 'px';
|
||||
//console.timeEnd('scroll resize');
|
||||
return;
|
||||
}
|
||||
//if(!height) return;
|
||||
|
||||
let divider = this.scrollSize / this.size / 0.5;
|
||||
this.thumbSize = this.size / divider;
|
||||
|
||||
if(this.thumbSize < 20) this.thumbSize = 20;
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.type] = this.thumbSize + 'px';
|
||||
console.timeEnd('scroll resize');
|
||||
return;
|
||||
}
|
||||
//if(!height) return;
|
||||
|
||||
let divider = this.scrollSize / this.size / 0.5;
|
||||
this.thumbSize = this.size / divider;
|
||||
|
||||
if(this.thumbSize < 20) this.thumbSize = 20;
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.type] = this.thumbSize + 'px';
|
||||
});
|
||||
|
||||
console.timeEnd('scroll resize');
|
||||
//console.timeEnd('scroll resize');
|
||||
|
||||
// @ts-ignore
|
||||
//console.log('onresize', thumb.style[type], thumbHeight, height);
|
||||
}
|
||||
|
||||
public setVirtualContainer(el?: HTMLElement) {
|
||||
public async setVirtualContainer(el?: HTMLElement) {
|
||||
this.splitUp = el;
|
||||
|
||||
this.hiddenElements.up.length = this.hiddenElements.down.length = 0;
|
||||
this.paddings.up = this.paddings.down = 0;
|
||||
|
||||
if(this.paddingTopDiv.parentElement) {
|
||||
this.paddingTopDiv.style.height = '';
|
||||
this.paddingBottomDiv.style.height = '';
|
||||
fastdom.mutate(() => {
|
||||
this.paddingTopDiv.style.height = '';
|
||||
this.paddingBottomDiv.style.height = '';
|
||||
});
|
||||
}
|
||||
|
||||
/* this.topObserver.unobserve(this.paddingTopDiv);
|
||||
this.bottomObserver.unobserve(this.paddingBottomDiv);
|
||||
|
||||
this.topObserver.observe(this.paddingTopDiv);
|
||||
this.bottomObserver.observe(this.paddingBottomDiv); */
|
||||
|
||||
if(el) {
|
||||
el.parentElement.insertBefore(this.paddingTopDiv, el);
|
||||
el.parentNode.insertBefore(this.paddingBottomDiv, el.nextSibling);
|
||||
fastdom.mutate(() => {
|
||||
el.parentElement.insertBefore(this.paddingTopDiv, el);
|
||||
el.parentNode.insertBefore(this.paddingBottomDiv, el.nextSibling);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public onScroll() {
|
||||
// @ts-ignore
|
||||
//let st = container[scrollSide];
|
||||
public async onScroll() {
|
||||
//console.time('scroll onScroll');
|
||||
let {value, maxValue} = await fastdom.measure(() => {
|
||||
// @ts-ignore
|
||||
if(this.container[this.scrollType] != this.scrollSize || this.thumbSize == 0) {
|
||||
this.resize();
|
||||
}
|
||||
|
||||
console.time('scroll onScroll');
|
||||
// @ts-ignore
|
||||
let value = this.container[this.scrollSide] / (this.scrollSize - this.size) * 100;
|
||||
let maxValue = 100 - (this.thumbSize / this.size * 100);
|
||||
|
||||
return {value, maxValue};
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
if(this.container[this.scrollType] != this.scrollSize || this.thumbSize == 0) {
|
||||
this.resize();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
let value = this.container[this.scrollSide] / (this.scrollSize - this.size) * 100;
|
||||
let maxValue = 100 - (this.thumbSize / this.size * 100);
|
||||
|
||||
//console.log('onscroll', container.scrollHeight, thumbHeight, height, value, maxValue);
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%';
|
||||
fastdom.mutate(() => {
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%';
|
||||
});
|
||||
|
||||
console.timeEnd('scroll onScroll');
|
||||
//console.timeEnd('scroll onScroll');
|
||||
}
|
||||
|
||||
public onTopIntersection(entry: IntersectionObserverEntry) {
|
||||
// console.log('onTopIntersection');
|
||||
public async onTopIntersection(entry: IntersectionObserverEntry) {
|
||||
console.log('onTopIntersection');
|
||||
|
||||
if(this.hiddenElements.up.length && this.paddings.up) {
|
||||
let needHeight = entry.intersectionRect.height + this.splitOffset;
|
||||
let needHeight = entry.intersectionRect.height || entry.boundingClientRect.height;
|
||||
|
||||
let fragment = document.createDocumentFragment();
|
||||
while(needHeight > 0 && this.paddings.up) {
|
||||
let child = this.hiddenElements.up.pop();
|
||||
|
||||
@ -300,29 +361,31 @@ export default class Scrollable {
|
||||
break;
|
||||
}
|
||||
|
||||
/* await new Promise((resolve, reject) => {
|
||||
window.requestAnimationFrame(resolve);
|
||||
}); */
|
||||
|
||||
this.splitUp.prepend(child.element);
|
||||
let height = child.height || child.element.scrollHeight;
|
||||
fragment.prepend(child.element);
|
||||
let height = child.height;
|
||||
|
||||
needHeight -= height;
|
||||
this.paddings.up -= height;
|
||||
|
||||
this.paddingTopDiv.style.height = this.paddings.up + 'px';
|
||||
}
|
||||
|
||||
await fastdom.mutate(() => {
|
||||
this.splitUp.prepend(fragment);
|
||||
this.paddingTopDiv.style.height = this.paddings.up + 'px';
|
||||
});
|
||||
} else {
|
||||
this.paddingTopDiv.style.height = '0px';
|
||||
await fastdom.mutate(() => {
|
||||
this.paddingTopDiv.style.height = '0px';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public onBottomIntersection(entry: IntersectionObserverEntry) {
|
||||
// console.log('onBottomIntersection');
|
||||
public async onBottomIntersection(entry: IntersectionObserverEntry) {
|
||||
console.log('onBottomIntersection');
|
||||
|
||||
if(this.hiddenElements.down.length && this.paddings.down) {
|
||||
let needHeight = entry.intersectionRect.height + this.splitOffset;
|
||||
let needHeight = entry.intersectionRect.height || entry.boundingClientRect.height;
|
||||
|
||||
let fragment = document.createDocumentFragment();
|
||||
while(needHeight > 0 && this.paddings.down) {
|
||||
let child = this.hiddenElements.down.shift();
|
||||
|
||||
@ -332,18 +395,22 @@ export default class Scrollable {
|
||||
break;
|
||||
}
|
||||
|
||||
this.splitUp.append(child.element);
|
||||
let height = child.height || child.element.scrollHeight;
|
||||
fragment.appendChild(child.element);
|
||||
let height = child.height;
|
||||
|
||||
needHeight -= height;
|
||||
this.paddings.down -= height;
|
||||
|
||||
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
|
||||
}
|
||||
|
||||
await fastdom.mutate(() => {
|
||||
this.splitUp.appendChild(fragment);
|
||||
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
|
||||
});
|
||||
if(this.onAddedBottom) this.onAddedBottom();
|
||||
} else {
|
||||
this.paddingBottomDiv.style.height = '0px';
|
||||
await fastdom.mutate(() => {
|
||||
this.paddingBottomDiv.style.height = '0px';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,16 +418,45 @@ export default class Scrollable {
|
||||
|
||||
}
|
||||
|
||||
public splitAppend(...smth: (string | Node)[]) {
|
||||
this.splitUp.append(...smth);
|
||||
public prepend(...smth: (string | Node)[]) {
|
||||
if(this.splitUp) {
|
||||
this.splitUp.prepend(...smth);
|
||||
|
||||
for(let node of smth) {
|
||||
if(typeof(node) !== 'string') {
|
||||
this.splitObserver.observe(node as Element);
|
||||
for(let node of smth) {
|
||||
if(typeof(node) !== 'string') {
|
||||
this.splitObserver.unobserve(node as Element);
|
||||
this.splitObserver.observe(node as Element);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.container.prepend(...smth);
|
||||
}
|
||||
}
|
||||
|
||||
public append(...smth: (string | Node)[]) {
|
||||
if(this.splitUp) {
|
||||
this.splitUp.append(...smth);
|
||||
|
||||
for(let node of smth) {
|
||||
if(typeof(node) !== 'string') {
|
||||
this.splitObserver.unobserve(node as Element);
|
||||
this.splitObserver.observe(node as Element);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.container.append(...smth);
|
||||
}
|
||||
}
|
||||
|
||||
public insertBefore(newChild: Element, refChild: Element) {
|
||||
if(this.splitUp) {
|
||||
this.splitObserver.unobserve(newChild);
|
||||
return this.splitUp.insertBefore(newChild, refChild);
|
||||
}
|
||||
|
||||
return this.container.insertBefore(newChild, refChild);
|
||||
}
|
||||
|
||||
set scrollTop(y: number) {
|
||||
this.container.scrollTop = y;
|
||||
}
|
||||
|
428
src/components/scrollable_good.ts
Normal file
428
src/components/scrollable_good.ts
Normal file
@ -0,0 +1,428 @@
|
||||
import { cancelEvent } from "../lib/utils";
|
||||
|
||||
//import {measure} from 'fastdom/fastdom.min';
|
||||
import {measure} from 'fastdom';
|
||||
|
||||
export default class Scrollable {
|
||||
public container: HTMLDivElement;
|
||||
public thumb: HTMLDivElement;
|
||||
|
||||
public type: string;
|
||||
public side: string;
|
||||
public scrollType: string;
|
||||
public scrollSide: string;
|
||||
public clientAxis: string;
|
||||
|
||||
public scrollSize = -1;
|
||||
public size = 0;
|
||||
public thumbSize = 0;
|
||||
|
||||
public hiddenElements: {
|
||||
up: {element: Element, height: number}[],
|
||||
down: {element: Element, height: number}[]
|
||||
} = {
|
||||
up: [],
|
||||
down: []
|
||||
};
|
||||
public paddings = {up: 0, down: 0};
|
||||
|
||||
public paddingTopDiv: HTMLDivElement;
|
||||
public paddingBottomDiv: HTMLDivElement;
|
||||
|
||||
public splitUp: HTMLElement;
|
||||
public splitOffset = 1500;
|
||||
|
||||
public onAddedBottom: () => void = null;
|
||||
|
||||
public topObserver: IntersectionObserver;
|
||||
public isTopIntersecting: boolean;
|
||||
public bottomObserver: IntersectionObserver;
|
||||
public isBottomIntersecting: boolean;
|
||||
|
||||
public splitObserver: IntersectionObserver;
|
||||
|
||||
constructor(public el: HTMLDivElement, x = false, y = true) {
|
||||
this.container = document.createElement('div');
|
||||
this.container.classList.add('scrollable');
|
||||
|
||||
let arr = [];
|
||||
for(let i = 0.001; i < 1; i += 0.001) arr.push(i);
|
||||
this.topObserver = new IntersectionObserver(entries => {
|
||||
let entry = entries[0];
|
||||
|
||||
// console.log('top intersection:', entries, this.isTopIntersecting, entry.isIntersecting, entry.intersectionRatio > 0);
|
||||
if(this.isTopIntersecting = entry.isIntersecting) {
|
||||
this.onTopIntersection(entry);
|
||||
}
|
||||
// console.log('top intersection end');
|
||||
}, {threshold: arr});
|
||||
|
||||
this.bottomObserver = new IntersectionObserver(entries => {
|
||||
let entry = entries[0];
|
||||
|
||||
// console.log('bottom intersection:', entries, this.isBottomIntersecting, entry.isIntersecting, entry.intersectionRatio > 0);
|
||||
if(this.isBottomIntersecting = entry.isIntersecting) {
|
||||
this.onBottomIntersection(entry);
|
||||
|
||||
if(this.onScrolledBottom) this.onScrolledBottom();
|
||||
}
|
||||
}, {threshold: arr});
|
||||
|
||||
this.splitObserver = new IntersectionObserver(entries => {
|
||||
//console.log('splitObserver', entries);
|
||||
|
||||
for(let entry of entries) {
|
||||
//console.log('onscroll entry', entry.target, entry.isIntersecting, entry);
|
||||
if(!entry.isIntersecting && entry.target.parentElement && entry.rootBounds) {
|
||||
let child = entry.target;
|
||||
//console.log('onscroll entry', entry.boundingClientRect, child, entry);
|
||||
|
||||
let isTop = entry.boundingClientRect.top <= 0;
|
||||
let isBottom = entry.rootBounds.height <= entry.boundingClientRect.top;
|
||||
|
||||
let needHeight = this.splitOffset;
|
||||
if(isTop) {
|
||||
let sliced: Element[] = [/* child */];
|
||||
|
||||
do {
|
||||
if(needHeight > 0) {
|
||||
needHeight -= child.scrollHeight;
|
||||
} else {
|
||||
sliced.push(child);
|
||||
}
|
||||
} while(child = child.previousElementSibling);
|
||||
|
||||
let length = sliced.length;
|
||||
for(let i = length - 1; i >= 0; --i) {
|
||||
let child = sliced[i];
|
||||
|
||||
let height = child.scrollHeight;
|
||||
this.paddings.up += height;
|
||||
this.hiddenElements.up.push({element: child, height});
|
||||
child.parentElement.removeChild(child);
|
||||
}
|
||||
|
||||
this.paddingTopDiv.style.height = this.paddings.up + 'px';
|
||||
//console.log('onscroll sliced up', sliced);
|
||||
} else if(isBottom) {
|
||||
let sliced: Element[] = [/* child */];
|
||||
|
||||
do {
|
||||
if(needHeight > 0) {
|
||||
needHeight -= child.scrollHeight;
|
||||
} else {
|
||||
sliced.push(child);
|
||||
}
|
||||
} while(child = child.nextElementSibling);
|
||||
|
||||
let length = sliced.length;
|
||||
for(let i = length - 1; i >= 0; --i) {
|
||||
let child = sliced[i];
|
||||
|
||||
let height = child.scrollHeight;
|
||||
this.paddings.down += height;
|
||||
this.hiddenElements.down.unshift({element: child, height});
|
||||
child.parentElement.removeChild(child);
|
||||
}
|
||||
|
||||
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
|
||||
//console.log('onscroll sliced down', sliced);
|
||||
}
|
||||
|
||||
//console.log('splitObserver', entry, entry.target, isTop);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(x) {
|
||||
this.container.classList.add('scrollable-x');
|
||||
this.type = 'width';
|
||||
this.side = 'left';
|
||||
this.scrollType = 'scrollWidth';
|
||||
this.scrollSide = 'scrollLeft';
|
||||
this.clientAxis = 'clientX';
|
||||
|
||||
let scrollHorizontally = (e: any) => {
|
||||
e = window.event || e;
|
||||
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
|
||||
this.container.scrollLeft -= (delta * 20);
|
||||
e.preventDefault();
|
||||
};
|
||||
if(this.container.addEventListener) {
|
||||
// IE9, Chrome, Safari, Opera
|
||||
this.container.addEventListener("mousewheel", scrollHorizontally, false);
|
||||
// Firefox
|
||||
this.container.addEventListener("DOMMouseScroll", scrollHorizontally, false);
|
||||
} else {
|
||||
// IE 6/7/8
|
||||
// @ts-ignore
|
||||
this.container.attachEvent("onmousewheel", scrollHorizontally);
|
||||
}
|
||||
} else if(y) {
|
||||
this.container.classList.add('scrollable-y');
|
||||
this.type = 'height';
|
||||
this.side = 'top';
|
||||
this.scrollType = 'scrollHeight';
|
||||
this.scrollSide = 'scrollTop';
|
||||
this.clientAxis = 'clientY';
|
||||
} else {
|
||||
throw new Error('no side for scroll');
|
||||
}
|
||||
|
||||
this.thumb = document.createElement('div');
|
||||
this.thumb.className = 'scrollbar-thumb';
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.type] = '30px';
|
||||
|
||||
let onMouseMove = (e: MouseEvent) => {
|
||||
let rect = this.thumb.getBoundingClientRect();
|
||||
|
||||
let diff: number;
|
||||
// @ts-ignore
|
||||
diff = e[this.clientAxis] - rect[this.side];
|
||||
// @ts-ignore
|
||||
this.container[this.scrollSide] += diff * 0.5;
|
||||
|
||||
// console.log('onMouseMove', e, diff);
|
||||
|
||||
cancelEvent(e);
|
||||
};
|
||||
|
||||
this.thumb.addEventListener('mousedown', () => {
|
||||
window.addEventListener('mousemove', onMouseMove);
|
||||
|
||||
window.addEventListener('mouseup', () => {
|
||||
window.removeEventListener('mousemove', onMouseMove);
|
||||
}, {once: true});
|
||||
});
|
||||
|
||||
//this.container.addEventListener('mouseover', this.resize.bind(this)); // omg
|
||||
window.addEventListener('resize', this.resize.bind(this));
|
||||
|
||||
this.paddingTopDiv = document.createElement('div');
|
||||
this.paddingTopDiv.classList.add('scroll-padding');
|
||||
this.paddingBottomDiv = document.createElement('div');
|
||||
this.paddingBottomDiv.classList.add('scroll-padding');
|
||||
|
||||
this.topObserver.observe(this.paddingTopDiv);
|
||||
this.bottomObserver.observe(this.paddingBottomDiv);
|
||||
|
||||
this.container.addEventListener('scroll', this.onScroll.bind(this));
|
||||
|
||||
//this.container.append(this.paddingTopDiv);
|
||||
Array.from(el.children).forEach(c => this.container.append(c));
|
||||
//this.container.append(this.paddingBottomDiv);
|
||||
|
||||
el.append(this.container);//container.append(el);
|
||||
this.container.parentElement.append(this.thumb);
|
||||
this.resize();
|
||||
}
|
||||
|
||||
public resize() {
|
||||
//console.time('scroll resize');
|
||||
// @ts-ignore
|
||||
this.scrollSize = this.container[this.scrollType];
|
||||
|
||||
let rect = this.container.getBoundingClientRect();
|
||||
|
||||
// @ts-ignore
|
||||
this.size = rect[this.type];
|
||||
|
||||
if(!this.size || this.size == this.scrollSize) {
|
||||
this.thumbSize = 0;
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.type] = this.thumbSize + 'px';
|
||||
//console.timeEnd('scroll resize');
|
||||
return;
|
||||
}
|
||||
//if(!height) return;
|
||||
|
||||
let divider = this.scrollSize / this.size / 0.5;
|
||||
this.thumbSize = this.size / divider;
|
||||
|
||||
if(this.thumbSize < 20) this.thumbSize = 20;
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.type] = this.thumbSize + 'px';
|
||||
|
||||
//console.timeEnd('scroll resize');
|
||||
|
||||
// @ts-ignore
|
||||
//console.log('onresize', thumb.style[type], thumbHeight, height);
|
||||
}
|
||||
|
||||
public setVirtualContainer(el?: HTMLElement) {
|
||||
this.splitUp = el;
|
||||
|
||||
this.hiddenElements.up.length = this.hiddenElements.down.length = 0;
|
||||
this.paddings.up = this.paddings.down = 0;
|
||||
|
||||
if(this.paddingTopDiv.parentElement) {
|
||||
this.paddingTopDiv.style.height = '';
|
||||
this.paddingBottomDiv.style.height = '';
|
||||
}
|
||||
|
||||
/* this.topObserver.unobserve(this.paddingTopDiv);
|
||||
this.bottomObserver.unobserve(this.paddingBottomDiv);
|
||||
|
||||
this.topObserver.observe(this.paddingTopDiv);
|
||||
this.bottomObserver.observe(this.paddingBottomDiv); */
|
||||
|
||||
if(el) {
|
||||
el.parentElement.insertBefore(this.paddingTopDiv, el);
|
||||
el.parentNode.insertBefore(this.paddingBottomDiv, el.nextSibling);
|
||||
}
|
||||
}
|
||||
|
||||
public onScroll() {
|
||||
// @ts-ignore
|
||||
//let st = container[scrollSide];
|
||||
|
||||
//console.time('scroll onScroll');
|
||||
|
||||
// @ts-ignore
|
||||
if(this.container[this.scrollType] != this.scrollSize || this.thumbSize == 0) {
|
||||
this.resize();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
let value = this.container[this.scrollSide] / (this.scrollSize - this.size) * 100;
|
||||
let maxValue = 100 - (this.thumbSize / this.size * 100);
|
||||
|
||||
//console.log('onscroll', container.scrollHeight, thumbHeight, height, value, maxValue);
|
||||
|
||||
// @ts-ignore
|
||||
this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%';
|
||||
|
||||
//console.timeEnd('scroll onScroll');
|
||||
}
|
||||
|
||||
public onTopIntersection(entry: IntersectionObserverEntry) {
|
||||
// console.log('onTopIntersection');
|
||||
|
||||
if(this.hiddenElements.up.length && this.paddings.up) {
|
||||
let needHeight = entry.intersectionRect.height + this.splitOffset;
|
||||
|
||||
while(needHeight > 0 && this.paddings.up) {
|
||||
let child = this.hiddenElements.up.pop();
|
||||
|
||||
// console.log('top returning from hidden', child);
|
||||
|
||||
if(!child) {
|
||||
this.paddings.up = 0;
|
||||
this.paddingTopDiv.style.height = '0px';
|
||||
break;
|
||||
}
|
||||
|
||||
/* await new Promise((resolve, reject) => {
|
||||
window.requestAnimationFrame(resolve);
|
||||
}); */
|
||||
|
||||
this.splitUp.prepend(child.element);
|
||||
let height = child.height || child.element.scrollHeight;
|
||||
|
||||
needHeight -= height;
|
||||
this.paddings.up -= height;
|
||||
|
||||
this.paddingTopDiv.style.height = this.paddings.up + 'px';
|
||||
}
|
||||
} else {
|
||||
this.paddingTopDiv.style.height = '0px';
|
||||
}
|
||||
}
|
||||
|
||||
public onBottomIntersection(entry: IntersectionObserverEntry) {
|
||||
// console.log('onBottomIntersection');
|
||||
|
||||
if(this.hiddenElements.down.length && this.paddings.down) {
|
||||
let needHeight = entry.intersectionRect.height + this.splitOffset;
|
||||
|
||||
while(needHeight > 0 && this.paddings.down) {
|
||||
let child = this.hiddenElements.down.shift();
|
||||
|
||||
if(!child) {
|
||||
this.paddings.down = 0;
|
||||
this.paddingBottomDiv.style.height = '0px';
|
||||
break;
|
||||
}
|
||||
|
||||
this.splitUp.append(child.element);
|
||||
let height = child.height || child.element.scrollHeight;
|
||||
|
||||
needHeight -= height;
|
||||
this.paddings.down -= height;
|
||||
|
||||
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
|
||||
}
|
||||
|
||||
if(this.onAddedBottom) this.onAddedBottom();
|
||||
} else {
|
||||
this.paddingBottomDiv.style.height = '0px';
|
||||
}
|
||||
}
|
||||
|
||||
public onScrolledBottom() {
|
||||
|
||||
}
|
||||
|
||||
public prepend(...smth: (string | Node)[]) {
|
||||
if(this.splitUp) {
|
||||
this.splitUp.prepend(...smth);
|
||||
|
||||
for(let node of smth) {
|
||||
if(typeof(node) !== 'string') {
|
||||
this.splitObserver.unobserve(node as Element);
|
||||
this.splitObserver.observe(node as Element);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.container.prepend(...smth);
|
||||
}
|
||||
}
|
||||
|
||||
public append(...smth: (string | Node)[]) {
|
||||
if(this.splitUp) {
|
||||
this.splitUp.append(...smth);
|
||||
|
||||
for(let node of smth) {
|
||||
if(typeof(node) !== 'string') {
|
||||
this.splitObserver.unobserve(node as Element);
|
||||
this.splitObserver.observe(node as Element);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.container.append(...smth);
|
||||
}
|
||||
}
|
||||
|
||||
public insertBefore(newChild: Element, refChild: Element) {
|
||||
if(this.splitUp) {
|
||||
this.splitObserver.unobserve(newChild);
|
||||
return this.splitUp.insertBefore(newChild, refChild);
|
||||
}
|
||||
|
||||
return this.container.insertBefore(newChild, refChild);
|
||||
}
|
||||
|
||||
set scrollTop(y: number) {
|
||||
this.container.scrollTop = y;
|
||||
}
|
||||
|
||||
get scrollTop() {
|
||||
return this.container.scrollTop;
|
||||
}
|
||||
|
||||
get scrollHeight() {
|
||||
return this.container.scrollHeight;
|
||||
}
|
||||
|
||||
get parentElement() {
|
||||
return this.container.parentElement;
|
||||
}
|
||||
|
||||
get offsetHeight() {
|
||||
return this.container.offsetHeight;
|
||||
}
|
||||
}
|
@ -329,7 +329,7 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
|
||||
let lastIndex = 0;
|
||||
interval = setInterval(() => {
|
||||
if(lastIndex >= svg.childElementCount) {
|
||||
if(lastIndex > svg.childElementCount || isNaN(audio.duration)) {
|
||||
clearInterval(interval);
|
||||
return;
|
||||
}
|
||||
@ -337,11 +337,14 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
// @ts-ignore
|
||||
timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true);
|
||||
|
||||
lastIndex = Math.round(audio.currentTime / audio.duration * 62);
|
||||
|
||||
//svg.children[lastIndex].setAttributeNS(null, 'fill', '#000');
|
||||
svg.children[lastIndex].classList.add('active');
|
||||
++lastIndex;
|
||||
//++lastIndex;
|
||||
//console.log('lastIndex:', lastIndex, audio.currentTime);
|
||||
}, duration * 1000 / svg.childElementCount | 0/* 63 * duration / 10 */);
|
||||
//}, duration * 1000 / svg.childElementCount | 0/* 63 * duration / 10 */);
|
||||
}, 20);
|
||||
} else {
|
||||
audio.pause();
|
||||
toggle.classList.add('tgico-largeplay');
|
||||
|
@ -1,6 +1,6 @@
|
||||
import apiManager from "../mtproto/apiManager";
|
||||
import apiFileManager from '../mtproto/apiFileManager';
|
||||
import { $rootScope, findUpTag, isElementInViewport, langPack } from "../utils";
|
||||
import { $rootScope, findUpTag, langPack } from "../utils";
|
||||
import appImManager from "./appImManager";
|
||||
import appPeersManager from './appPeersManager';
|
||||
import appMessagesManager from "./appMessagesManager";
|
||||
@ -8,6 +8,7 @@ import appUsersManager from "./appUsersManager";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
import { ripple } from "../../components/misc";
|
||||
import appSidebarLeft from "./appSidebarLeft";
|
||||
import Scrollable from "../../components/scrollable";
|
||||
|
||||
type DialogDom = {
|
||||
avatarDiv: HTMLDivElement,
|
||||
@ -25,8 +26,8 @@ export class AppDialogsManager {
|
||||
public chatList = document.getElementById('dialogs') as HTMLUListElement;
|
||||
public chatListArchived = document.getElementById('dialogs-archived') as HTMLUListElement;
|
||||
public pinnedDelimiter: HTMLDivElement;
|
||||
public chatsHidden: any;
|
||||
public chatsArchivedHidden: any;
|
||||
public chatsHidden: Scrollable["hiddenElements"];
|
||||
public chatsArchivedHidden: Scrollable["hiddenElements"];
|
||||
|
||||
public myID = 0;
|
||||
public doms: {[peerID: number]: DialogDom} = {};
|
||||
@ -153,7 +154,7 @@ export class AppDialogsManager {
|
||||
}
|
||||
|
||||
public sortDom(archived = false) {
|
||||
return;
|
||||
// return;
|
||||
|
||||
let dialogs = appMessagesManager.dialogsStorage.dialogs.slice();
|
||||
|
||||
@ -205,6 +206,9 @@ export class AppDialogsManager {
|
||||
|
||||
let hiddenLength: number = chatsHidden.up.length;
|
||||
let inViewportLength = chatList.childElementCount;
|
||||
let hiddenConcated = chatsHidden.up.concat(chatsHidden.down);
|
||||
|
||||
//console.log('sortDom clearing innerHTML', archived, hiddenLength, inViewportLength);
|
||||
|
||||
chatList.innerHTML = '';
|
||||
|
||||
@ -214,16 +218,18 @@ export class AppDialogsManager {
|
||||
if(!dom) return;
|
||||
|
||||
if(inUpper.length < hiddenLength) {
|
||||
inUpper.push({element: dom.listEl, height: 0});
|
||||
let child = hiddenConcated.find(obj => obj.element == dom.listEl);
|
||||
inUpper.push({element: dom.listEl, height: child ? child.height : 0});
|
||||
} else if(inViewportIndex <= inViewportLength - 1) {
|
||||
chatList.append(dom.listEl);
|
||||
++inViewportIndex;
|
||||
} else {
|
||||
inBottom.push({element: dom.listEl, height: 0});
|
||||
let child = hiddenConcated.find(obj => obj.element == dom.listEl);
|
||||
inBottom.push({element: dom.listEl, height: child ? child.height : 0});
|
||||
}
|
||||
});
|
||||
|
||||
//////console.log('sortDom', sorted.length, inUpper.length, chatList.childElementCount, inBottom.length);
|
||||
//console.log('sortDom', sorted.length, inUpper.length, chatList.childElementCount, inBottom.length);
|
||||
|
||||
chatsHidden.up = inUpper;
|
||||
chatsHidden.down = inBottom;
|
||||
@ -524,7 +530,7 @@ export class AppDialogsManager {
|
||||
this.domsArchived[dialog.peerID] = dom;
|
||||
} else {
|
||||
//this.chatList.append(li);
|
||||
appSidebarLeft.scroll.splitAppend(li);
|
||||
appSidebarLeft.scroll.append(li);
|
||||
this.doms[dialog.peerID] = dom;
|
||||
}
|
||||
|
||||
|
@ -70,8 +70,6 @@ export class AppImManager {
|
||||
public chatInner = document.getElementById('bubbles-inner') as HTMLDivElement;
|
||||
public searchBtn = this.pageEl.querySelector('.chat-search-button') as HTMLButtonElement;
|
||||
public goDownBtn = this.pageEl.querySelector('#bubbles-go-down') as HTMLButtonElement;
|
||||
public firstContainerDiv: HTMLDivElement;
|
||||
public lastContainerDiv: HTMLDivElement;
|
||||
private getHistoryPromise: Promise<boolean>;
|
||||
private getHistoryTimeout = 0;
|
||||
|
||||
@ -185,7 +183,7 @@ export class AppImManager {
|
||||
|
||||
this.renderMessagesByIDs(msgIDs);
|
||||
|
||||
appDialogsManager.sortDom();
|
||||
//appDialogsManager.sortDom();
|
||||
});
|
||||
|
||||
$rootScope.$on('history_delete', (e: CustomEvent) => {
|
||||
@ -627,6 +625,8 @@ export class AppImManager {
|
||||
}
|
||||
|
||||
public deleteEmptySideDivs() {
|
||||
return;
|
||||
|
||||
let nodes = Array.from(this.chatInner.childNodes) as HTMLDivElement[];
|
||||
nodes.filter((node) => {
|
||||
let childElementCount = node.childElementCount;
|
||||
@ -844,10 +844,10 @@ export class AppImManager {
|
||||
}
|
||||
|
||||
public setScroll() {
|
||||
this.scrollable = new Scrollable(this.bubblesContainer);
|
||||
this.scrollable = new Scrollable(this.bubblesContainer, false, true, 1500);
|
||||
this.scroll = this.scrollable.container;
|
||||
|
||||
//this.scrollable.setVirtualContainer(this.chatInner);
|
||||
this.scrollable.setVirtualContainer(this.chatInner);
|
||||
|
||||
this.scrollPosition = new ScrollPosition(this.chatInner);
|
||||
this.scroll.addEventListener('scroll', this.onScroll.bind(this));
|
||||
@ -949,11 +949,6 @@ export class AppImManager {
|
||||
this.scrolledAllDown = false;
|
||||
this.muted = false;
|
||||
|
||||
if(this.lastContainerDiv) this.lastContainerDiv.remove();
|
||||
if(this.firstContainerDiv) this.firstContainerDiv.remove();
|
||||
this.lastContainerDiv = undefined;
|
||||
this.firstContainerDiv = undefined;
|
||||
|
||||
for(let i in this.bubbles) {
|
||||
let bubble = this.bubbles[i];
|
||||
bubble.remove();
|
||||
@ -975,6 +970,8 @@ export class AppImManager {
|
||||
// clear messages
|
||||
this.chatInner.innerHTML = '';
|
||||
|
||||
this.scrollable.setVirtualContainer(this.chatInner);
|
||||
|
||||
//appSidebarRight.minMediaID = {};
|
||||
}
|
||||
|
||||
@ -1635,10 +1632,15 @@ export class AppImManager {
|
||||
|
||||
if(updatePosition) {
|
||||
bubble.classList.add(our ? 'is-out' : 'is-in');
|
||||
if(reverse) {
|
||||
/* if(reverse) {
|
||||
this.chatInner.prepend(bubble);
|
||||
} else {
|
||||
this.chatInner.append(bubble);
|
||||
} */
|
||||
if(reverse) {
|
||||
this.scrollable.prepend(bubble);
|
||||
} else {
|
||||
this.scrollable.append(bubble);
|
||||
}
|
||||
|
||||
let justDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
@ -1673,12 +1675,12 @@ export class AppImManager {
|
||||
|
||||
//this.chatInner.insertBefore(div, containerDiv);
|
||||
//containerDiv.insertBefore(div, bubble);
|
||||
this.chatInner.insertBefore(div, bubble);
|
||||
this.scrollable.insertBefore(div, bubble);// this.chatInner.insertBefore(div, bubble);
|
||||
} else {
|
||||
let dateMessage = this.dateMessages[dateTimestamp];
|
||||
if(dateMessage.firstTimestamp > date.getTime()) {
|
||||
//this.chatInner.insertBefore(dateMessage.div, containerDiv);
|
||||
this.chatInner.insertBefore(dateMessage.div, bubble);
|
||||
this.scrollable.insertBefore(dateMessage.div, bubble);// this.chatInner.insertBefore(dateMessage.div, bubble);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1707,7 +1709,7 @@ export class AppImManager {
|
||||
|
||||
let loadCount = Object.keys(this.bubbles).length > 0 ?
|
||||
20 :
|
||||
(this.chatInner.parentElement.parentElement.scrollHeight) / 30 * 1.25 | 0;
|
||||
this.scrollable.container.parentElement.scrollHeight / 30 * 1.25 | 0;
|
||||
|
||||
/* if(testScroll) {
|
||||
loadCount = 1;
|
||||
|
@ -7,6 +7,9 @@ import apiFileManager from "../mtproto/apiFileManager";
|
||||
import apiManager from "../mtproto/apiManager";
|
||||
//import { MTPhotoSize } from "../../components/misc";
|
||||
|
||||
//import fastdom from "fastdom";
|
||||
//import 'fastdom/fastdom-strict'; // exclude in production
|
||||
|
||||
type MTPhoto = {
|
||||
_: 'photo',
|
||||
pFlags: any,
|
||||
@ -24,22 +27,26 @@ export class AppPhotosManager {
|
||||
private photos: {
|
||||
[id: string]: MTPhoto
|
||||
} = {};
|
||||
public windowW = document.body.scrollWidth;
|
||||
public windowH = document.body.scrollHeight;
|
||||
public windowW = 0;
|
||||
public windowH = 0;
|
||||
|
||||
public static jf = new Uint8Array(bytesFromHex('ffd8ffe000104a46494600010100000100010000ffdb004300281c1e231e19282321232d2b28303c64413c37373c7b585d4964918099968f808c8aa0b4e6c3a0aadaad8a8cc8ffcbdaeef5ffffff9bc1fffffffaffe6fdfff8ffdb0043012b2d2d3c353c76414176f8a58ca5f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8ffc00011080000000003012200021101031101ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00'));
|
||||
public static Df = bytesFromHex('ffd9');
|
||||
|
||||
constructor() {
|
||||
window.addEventListener('resize', (e) => {
|
||||
this.windowW = document.body.scrollWidth;
|
||||
this.windowH = document.body.scrollHeight;
|
||||
|
||||
//fastdom.measure(() => {
|
||||
this.windowW = document.body.scrollWidth;
|
||||
this.windowH = document.body.scrollHeight;
|
||||
//});
|
||||
//console.log(`Set windowW, windowH: ${this.windowW}x${this.windowH}`);
|
||||
});
|
||||
|
||||
/* $rootScope.openPhoto = openPhoto
|
||||
$rootScope.preloadPhoto = preloadPhoto; */
|
||||
|
||||
//fastdom.measure(() => {
|
||||
console.log('measure works');
|
||||
this.windowW = document.body.scrollWidth;
|
||||
this.windowH = document.body.scrollHeight;
|
||||
//});
|
||||
}
|
||||
|
||||
public savePhoto(apiPhoto: any, context?: any) {
|
||||
|
@ -3,7 +3,7 @@ import { putPreloader, formatPhoneNumber } from "../../components/misc";
|
||||
import Scrollable from '../../components/scrollable';
|
||||
import appMessagesManager, { AppMessagesManager } from "./appMessagesManager";
|
||||
import appDialogsManager from "./appDialogsManager";
|
||||
import { isElementInViewport, numberWithCommas, cancelEvent } from "../utils";
|
||||
import { isElementInViewport, numberWithCommas } from "../utils";
|
||||
import appMessagesIDsManager from "./appMessagesIDsManager";
|
||||
import appImManager from "./appImManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
@ -25,7 +25,7 @@ class SearchGroup {
|
||||
this.container.append(this.nameEl, this.list);
|
||||
this.container.style.display = 'none';
|
||||
|
||||
appDialogsManager.setListClickListener(this.list);
|
||||
//appDialogsManager.setListClickListener(this.list);
|
||||
}
|
||||
|
||||
clear() {
|
||||
@ -88,7 +88,7 @@ class AppSidebarLeft {
|
||||
this.chatsPreloader = document.createElement('div');
|
||||
this.chatsPreloader.classList.add('preloader');
|
||||
putPreloader(this.chatsPreloader);
|
||||
this.chatsContainer.append(this.chatsPreloader);
|
||||
//this.chatsContainer.append(this.chatsPreloader);
|
||||
|
||||
this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
|
||||
|
||||
@ -128,20 +128,16 @@ class AppSidebarLeft {
|
||||
//this.toolsBtn.classList.add('tgico-back');
|
||||
});
|
||||
|
||||
/* this.listsContainer.insertBefore(this.searchMessagesList, this.listsContainer.lastElementChild);
|
||||
for(let i = 0; i < 25; ++i) {
|
||||
/* for(let i = 0; i < 100; ++i) {
|
||||
let li = document.createElement('li');
|
||||
li.innerHTML = `<div class="user-avatar is-online" style="font-size: 0px;"><img src="assets/img/camomile.jpg"></div><div class="user-caption"><p><span class="user-title">Влад</span><span><span class="message-status"></span><span class="message-time">14:41</span></span></p><p><span class="user-last-message">это важно</span><span class="tgico-pinnedchat"></span></p></div><div class="c-ripple"><span class="c-ripple__circle" style="top: 65px; left: 338.5px;"></span></div>`;
|
||||
this.searchMessagesList.append(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="blob:https://localhost:9000/ce99a2a3-f34b-4ca1-a09e-f716f89930d8"></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>Гагагагга</span><span></span></p></div></div>`;
|
||||
this.scroll.append(li);
|
||||
} */
|
||||
|
||||
this.listsContainer.addEventListener('scroll', this.onSidebarScroll.bind(this));
|
||||
|
||||
//this.searchContainer.append(this.listsContainer);
|
||||
|
||||
|
||||
this.searchInput.addEventListener('focus', (e) => {
|
||||
/* this.toolsBtn.classList.remove('tgico-menu', 'btn-menu-toggle');
|
||||
this.toolsBtn.classList.add('tgico-back'); */
|
||||
this.toolsBtn.classList.remove('active');
|
||||
this.backBtn.classList.add('active');
|
||||
this.searchContainer.classList.add('active');
|
||||
@ -154,17 +150,10 @@ class AppSidebarLeft {
|
||||
|
||||
this.searchInput.addEventListener('blur', (e) => {
|
||||
if(!this.searchInput.value) {
|
||||
/* this.toolsBtn.classList.add('tgico-menu');
|
||||
this.toolsBtn.classList.remove('tgico-back'); */
|
||||
this.toolsBtn.classList.add('active');
|
||||
this.backBtn.classList.remove('active');
|
||||
this.searchContainer.classList.remove('active');
|
||||
this.backBtn.click();
|
||||
|
||||
/* setTimeout(() => {
|
||||
//this.toolsBtn.click();
|
||||
this.toolsBtn.classList.add('btn-menu-toggle');
|
||||
}, 200); */
|
||||
}
|
||||
|
||||
/* this.peerID = 0;
|
||||
@ -223,6 +212,8 @@ class AppSidebarLeft {
|
||||
}
|
||||
|
||||
public async loadDialogs(archived = false) {
|
||||
//return;
|
||||
|
||||
if(this.loadDialogsPromise/* || 1 == 1 */) return this.loadDialogsPromise;
|
||||
|
||||
(archived ? this.chatsArchivedContainer : this.chatsContainer).append(this.chatsPreloader);
|
||||
|
@ -32,7 +32,7 @@ export const appDocsManager = AppDocsManager;
|
||||
export const appSidebarRight = AppSidebarRight;
|
||||
export const appSidebarLeft = AppSidebarLeft;
|
||||
|
||||
/* (window as any).Services = {
|
||||
(window as any).Services = {
|
||||
appUsersManager,
|
||||
appChatsManager,
|
||||
apiUpdatesManager,
|
||||
@ -48,4 +48,4 @@ export const appSidebarLeft = AppSidebarLeft;
|
||||
appSidebarRight,
|
||||
appSidebarLeft
|
||||
//appSharedMediaManager
|
||||
}; */
|
||||
};
|
||||
|
@ -70,9 +70,9 @@
|
||||
margin: 0 8.5px 0 8px;
|
||||
overflow: hidden;
|
||||
|
||||
/* &:hover {
|
||||
&:hover {
|
||||
background: rgba(112, 117, 121, .08);
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
li.active > .rp {
|
||||
|
Loading…
x
Reference in New Issue
Block a user