Browse Source

virtual chatlist scroll (care)

master
Eduard Kuzmenko 5 years ago
parent
commit
be4205e5cc
  1. BIN
      .DS_Store
  2. 127
      src/components/misc.ts
  3. 71
      src/components/pageIm.ts
  4. 2
      src/components/pageSignIn.ts
  5. 57
      src/lib/appManagers/appDialogsManager.ts
  6. 60
      src/lib/appManagers/appImManager.ts
  7. 2
      src/lib/appManagers/appMessagesIDsManager.ts
  8. 32
      src/lib/appManagers/appMessagesManager.ts
  9. 142
      src/lib/appManagers/appSidebarLeft.ts
  10. 43
      src/lib/appManagers/appSidebarRight.ts
  11. 41
      src/scss/materialize.scss
  12. 7
      src/scss/partials/_leftSidebar.scss

BIN
.DS_Store vendored

Binary file not shown.

127
src/components/misc.ts

@ -376,62 +376,151 @@ export function scrollable(el: HTMLDivElement, x = false, y = true) { @@ -376,62 +376,151 @@ export function scrollable(el: HTMLDivElement, x = false, y = true) {
let resize = () => {
// @ts-ignore
scrollHeight = container[scrollType];
scrollSize = container[scrollType];
let rect = container.getBoundingClientRect();
// @ts-ignore
height = rect[type];
size = rect[type];
if(!height || height == scrollHeight) {
thumbHeight = 0;
if(!size || size == scrollSize) {
thumbSize = 0;
// @ts-ignore
thumb.style[type] = thumbHeight + 'px';
thumb.style[type] = thumbSize + 'px';
return;
}
//if(!height) return;
let divider = scrollHeight / height / 0.5;
thumbHeight = height / divider;
let divider = scrollSize / size / 0.5;
thumbSize = size / divider;
if(thumbHeight < 20) thumbHeight = 20;
if(thumbSize < 20) thumbSize = 20;
// @ts-ignore
thumb.style[type] = thumbHeight + 'px';
thumb.style[type] = thumbSize + 'px';
// @ts-ignore
//console.log('onresize', thumb.style[type], thumbHeight, height);
};
let scrollHeight = -1;
let height = 0;
let thumbHeight = 0;
let scrollSize = -1;
let size = 0;
let thumbSize = 0;
window.addEventListener('resize', resize);
//container.addEventListener('DOMNodeInserted', resize);
container.addEventListener('scroll', (e) => {
let hiddenElements: {
up: Element[],
down: Element[]
} = {
up: [],
down: []
};
let paddings = {up: 0, down: 0};
let paddingTopDiv = document.createElement('div');
paddingTopDiv.classList.add('scroll-padding');
let paddingBottomDiv = document.createElement('div');
paddingBottomDiv.classList.add('scroll-padding');
let onScroll = (e: Event) => {
// @ts-ignore
//let st = container[scrollSide];
// @ts-ignore
if(container[scrollType] != scrollHeight || thumbHeight == 0) {
if(container[scrollType] != scrollSize || thumbSize == 0) {
resize();
}
let splitUp = container.querySelector('ul');
let children = Array.from(splitUp.children) as HTMLElement[];
let firstVisible = -1, lastVisible = -1;
let length = children.length;
for(let i = 0; i < length; ++i) {
let child = children[i];
if(isElementInViewport(child)) {
if(firstVisible < 0) firstVisible = i;
lastVisible = i;
}
}
if(firstVisible > 0) {
let sliced = children.slice(0, firstVisible);
for(let child of sliced) {
paddings.up += child.scrollHeight;
hiddenElements.up.push(child);
child.parentElement.removeChild(child);
}
//console.log('sliced up', sliced.length);
//sliced.forEach(child => child.style.display = 'none');
paddingTopDiv.style.height = paddings.up + 'px';
//console.log('onscroll need to add padding: ', paddings.up);
} else if(hiddenElements.up.length) {
while(isElementInViewport(paddingTopDiv) && paddings.up) {
let child = hiddenElements.up.pop();
splitUp.prepend(child);
paddings.up -= child.scrollHeight;
paddingTopDiv.style.height = paddings.up + 'px';
}
}
if(lastVisible < (length - 1)) {
let sliced = children.slice(lastVisible + 1).reverse();
for(let child of sliced) {
paddings.down += child.scrollHeight;
hiddenElements.down.unshift(child);
child.parentElement.removeChild(child);
}
//console.log('onscroll sliced down', sliced.length);
//sliced.forEach(child => child.style.display = 'none');
paddingBottomDiv.style.height = paddings.down + 'px';
//console.log('onscroll need to add padding: ', paddings.up);
} else if(hiddenElements.down.length) {
while(isElementInViewport(paddingBottomDiv) && paddings.down) {
let child = hiddenElements.down.shift();
splitUp.append(child);
paddings.down -= child.scrollHeight;
paddingBottomDiv.style.height = paddings.down + 'px';
}
}
//console.log('onscroll', container, firstVisible, lastVisible, hiddenElements);
// @ts-ignore
let value = container[scrollSide] / (scrollHeight - height) * 100;
let maxValue = 100 - (thumbHeight / height * 100);
let value = container[scrollSide] / (scrollSize - size) * 100;
let maxValue = 100 - (thumbSize / size * 100);
//console.log('onscroll', container.scrollHeight, thumbHeight, height, value, maxValue);
// @ts-ignore
thumb.style[side] = (value >= maxValue ? maxValue : value) + '%';
});
//lastScrollPos = st;
};
let lastScrollPos = 0;
container.addEventListener('scroll', onScroll);
container.append(paddingTopDiv);
Array.from(el.children).forEach(c => container.append(c));
container.append(paddingBottomDiv);
el.append(container);//container.append(el);
container.parentElement.append(thumb);
resize();
return container;
return {container, hiddenElements, onScroll};
}
export function wrapPhoto(this: AppImManager, photo: any, message: any, container: HTMLDivElement) {

71
src/components/pageIm.ts

@ -13,6 +13,7 @@ import appStickersManager, { MTStickerSet } from "../lib/appManagers/appStickers @@ -13,6 +13,7 @@ import appStickersManager, { MTStickerSet } from "../lib/appManagers/appStickers
import { AppImManager } from "../lib/appManagers/appImManager";
import { AppMessagesManager } from "../lib/appManagers/appMessagesManager";
import appSidebarRight from "../lib/appManagers/appSidebarRight";
import appSidebarLeft from "../lib/appManagers/appSidebarLeft";
const EMOTICONSSTICKERGROUP = 'emoticons-dropdown';
@ -175,7 +176,7 @@ let initEmoticonsDropdown = (pageEl: HTMLDivElement, @@ -175,7 +176,7 @@ let initEmoticonsDropdown = (pageEl: HTMLDivElement,
let prevCategoryIndex = 1;
let menu = contentEmojiDiv.nextElementSibling as HTMLUListElement;
let emojiScroll = scrollable(contentEmojiDiv);
let emojiScroll = scrollable(contentEmojiDiv).container;
emojiScroll.addEventListener('scroll', (e) => {
prevCategoryIndex = emoticonsContentOnScroll(menu, heights, prevCategoryIndex, emojiScroll);
});
@ -341,7 +342,7 @@ let initEmoticonsDropdown = (pageEl: HTMLDivElement, @@ -341,7 +342,7 @@ let initEmoticonsDropdown = (pageEl: HTMLDivElement,
});
let prevCategoryIndex = 0;
let stickersScroll = scrollable(contentStickersDiv);
let stickersScroll = scrollable(contentStickersDiv).container;
stickersScroll.addEventListener('scroll', (e) => {
lazyLoadQueue.check();
lottieLoader.checkAnimations();
@ -362,72 +363,15 @@ export default () => import('../lib/services').then(services => { @@ -362,72 +363,15 @@ export default () => import('../lib/services').then(services => {
let {appImManager, appMessagesManager, appDialogsManager, apiUpdatesManager, appUsersManager} = services;
//export default () => {
let chatsContainer = document.getElementById('chats-container') as HTMLDivElement;
let d = document.createElement('div');
d.classList.add('preloader');
putPreloader(d);
chatsContainer.append(d);
let pageEl = document.body.getElementsByClassName('page-chats')[0] as HTMLDivElement;
pageEl.style.display = '';
const loadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
let chatsScroll = scrollable(chatsContainer as HTMLDivElement);
let sidebarScroll = scrollable(document.body.querySelector('.profile-container'));
let chatScroll = scrollable(document.getElementById('bubbles') as HTMLDivElement);
let sidebarScroll = scrollable(document.body.querySelector('.profile-container')).container;
let chatScroll = scrollable(document.getElementById('bubbles') as HTMLDivElement).container;
apiUpdatesManager.attach();
let offsetIndex = 0;
let loadDialogsPromise: Promise<any>;
let loadDialogs = async() => {
if(loadDialogsPromise) return loadDialogsPromise;
chatsContainer.append(d);
//let offset = appMessagesManager.generateDialogIndex();/* appMessagesManager.dialogsNum */;
try {
loadDialogsPromise = appMessagesManager.getConversations('', offsetIndex, loadCount);
let result = await loadDialogsPromise;
console.log('loaded ' + loadCount + ' dialogs by offset:', offsetIndex, result);
if(result && result.dialogs && result.dialogs.length) {
offsetIndex = result.dialogs[result.dialogs.length - 1].index;
result.dialogs.forEach((dialog: any) => {
appDialogsManager.addDialog(dialog);
});
}
} catch(err) {
console.error(err);
}
d.remove();
loadDialogsPromise = undefined;
};
let onScroll = () => {
if(!loadDialogsPromise) {
let d = Array.from(appDialogsManager.chatList.childNodes).slice(-5);
for(let node of d) {
if(isElementInViewport(node)) {
loadDialogs();
break;
}
}
//console.log('last 5 dialogs:', d);
}
};
chatsScroll.addEventListener('scroll', onScroll);
window.addEventListener('resize', () => {
setTimeout(onScroll, 0);
});
// @ts-ignore
document.addEventListener('user_update', (e: CustomEvent) => {
let userID = e.detail;
@ -797,9 +741,8 @@ export default () => import('../lib/services').then(services => { @@ -797,9 +741,8 @@ export default () => import('../lib/services').then(services => {
});
});
loadDialogs().then(result => {
onScroll();
appSidebarLeft.loadDialogs().then(result => {
appSidebarLeft.onChatsScroll();
appImManager.setScroll(chatScroll);
appSidebarRight.setScroll(sidebarScroll);
});

2
src/components/pageSignIn.ts

@ -51,7 +51,7 @@ export default () => { @@ -51,7 +51,7 @@ export default () => {
wrapper.appendChild(list);
//let wrapperScroll = OverlayScrollbars(wrapper, (window as any).scrollbarOptions);
let wrapperScroll = scrollable(wrapper);
scrollable(wrapper);
let initedSelect = false;

57
src/lib/appManagers/appDialogsManager.ts

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
import apiManager from "../mtproto/apiManager";
import apiFileManager from '../mtproto/apiFileManager';
import { $rootScope, findUpTag } from "../utils";
import { $rootScope, findUpTag, isElementInViewport } from "../utils";
import appImManager from "./appImManager";
import appPeersManager from './appPeersManager';
import appMessagesManager from "./appMessagesManager";
@ -20,11 +20,9 @@ type DialogDom = { @@ -20,11 +20,9 @@ type DialogDom = {
};
export class AppDialogsManager {
public pinnedChatList = document.getElementById('dialogs-pinned') as HTMLUListElement;
public chatList = document.getElementById('dialogs') as HTMLUListElement;
public chatsHidden: any;
public myID = 0;
public doms: {[x: number]: any} = {};
@ -40,7 +38,6 @@ export class AppDialogsManager { @@ -40,7 +38,6 @@ export class AppDialogsManager {
//let chatClosedDiv = document.getElementById('chat-closed');
this.setListClickListener(this.pinnedChatList);
this.setListClickListener(this.chatList);
}
@ -131,20 +128,54 @@ export class AppDialogsManager { @@ -131,20 +128,54 @@ export class AppDialogsManager {
}
public sortDom() {
/* let sorted = */appMessagesManager.dialogsStorage.dialogs
console.log('sortDom');
//return;
let dialogs = appMessagesManager.dialogsStorage.dialogs;
let inUpper: HTMLLIElement[] = [];
let inBottom: HTMLLIElement[] = [];
let lastPinnedIndex = -1;
for(let i = 0; i < dialogs.length; ++i) {
let dialog = dialogs[i];
if(!dialog.pFlags.pinned) break;
lastPinnedIndex = i;
}
let sorted = dialogs
.filter((d: any) => !d.pFlags.pinned)
.sort((a: any, b: any) => {
let timeA = appMessagesManager.getMessage(a.top_message).date;
let timeB = appMessagesManager.getMessage(b.top_message).date;
return timeB - timeA;
})
.forEach((d: any) => {
});
if(lastPinnedIndex != -1) {
sorted = dialogs.slice(0, lastPinnedIndex + 1).concat(sorted);
}
let inViewportIndex = -1;
sorted.forEach((d: any) => {
let dom = this.getDialogDom(d.peerID);
if(!dom) return;
this.chatList.append(dom.listEl);
if(this.chatsHidden.up.find((d: HTMLLIElement) => d === dom.listEl)) {
inUpper.push(dom.listEl);
} else if(isElementInViewport(dom.listEl)) {
this.chatList.insertBefore(dom.listEl, this.chatList.children[++inViewportIndex]);
} else if(this.chatsHidden.down.find((d: HTMLLIElement) => d === dom.listEl)) {
inBottom.push(dom.listEl);
} else {
console.warn('found no dom!', dom);
}
//this.chatList.append(dom.listEl);
});
this.chatsHidden.up = inUpper;
this.chatsHidden.down = inBottom;
}
public setLastMessage(dialog: any, lastMessage?: any, dom?: DialogDom) {
@ -405,7 +436,13 @@ export class AppDialogsManager { @@ -405,7 +436,13 @@ export class AppDialogsManager {
};
if(!container) {
(dialog.pFlags.pinned ? this.pinnedChatList : this.chatList).append(li);
this.chatList.append(li);
//this.appendTo.push(li);
if(dialog.pFlags.pinned) {
li.classList.add('dialog-pinned');
}
this.doms[dialog.peerID] = dom;
this.setLastMessage(dialog);
} else {

60
src/lib/appManagers/appImManager.ts

@ -132,6 +132,7 @@ export class AppImManager { @@ -132,6 +132,7 @@ export class AppImManager {
private topbar: HTMLDivElement = null;
private chatInput: HTMLDivElement = null;
scrolledAll: boolean;
constructor() {
this.log = logger('IM');
@ -380,30 +381,39 @@ export class AppImManager { @@ -380,30 +381,39 @@ export class AppImManager {
// load more history
if(!this.getHistoryPromise && !this.getHistoryTimeout /* && false */) {
let history = Object.keys(this.bubbles).map(id => +id).sort();
/* let history = appMessagesManager.historiesStorage[this.peerID].history;
let length = history.length; */
this.getHistoryTimeout = setTimeout(() => { // must be
let history = Object.keys(this.bubbles).map(id => +id).sort();
/* let history = appMessagesManager.historiesStorage[this.peerID].history;
let length = history.length; */
// filter negative ids
for(let i = 0; i < history.length; ++i) {
if(history[i] <= 0) history.splice(i, 1);
else break;
}
this.getHistoryTimeout = 0;
let willLoad = false;
for(let i = 0; i < 10; ++i) {
let msgID = history[i];
if(!(msgID in this.bubbles) || msgID <= 0) continue;
let bubble = this.bubbles[msgID];
if(isElementInViewport(bubble)) {
willLoad = true;
this.log('Will load more (up) history by id:', history[0], 'maxID:', history[history.length - 1], history, bubble);
/* false && */!testScroll && this.getHistory(history[0], true).then(() => { // uncomment
this.onScroll();
}).catch(err => {
this.log.warn('Could not load more history, err:', err);
});
if(!this.scrolledAll) {
for(let i = 0; i < 10; ++i) {
let msgID = history[i];
let bubble = this.bubbles[msgID];
if(isElementInViewport(bubble)) {
willLoad = true;
break;
this.log('Will load more (up) history by id:', history[0], 'maxID:', history[history.length - 1], history, bubble);
/* false && */!testScroll && this.getHistory(history[0], true).then(() => { // uncomment
this.onScroll();
}).catch(err => {
this.log.warn('Could not load more history, err:', err);
});
break;
}
}
}
@ -413,8 +423,6 @@ export class AppImManager { @@ -413,8 +423,6 @@ export class AppImManager {
if(!willLoad && history.indexOf(/* this.lastDialog */dialog.top_message) === -1) {
let lastMsgIDs = history.slice(-10);
for(let msgID of lastMsgIDs) {
if(!(msgID in this.bubbles) || msgID <= 0) continue;
let bubble = this.bubbles[msgID];
if(isElementInViewport(bubble)) {
@ -520,6 +528,7 @@ export class AppImManager { @@ -520,6 +528,7 @@ export class AppImManager {
public cleanup() {
this.peerID = $rootScope.selectedPeerID = 0;
this.scrolledAll = false;
if(this.lastContainerDiv) this.lastContainerDiv.remove();
if(this.firstContainerDiv) this.firstContainerDiv.remove();
@ -645,7 +654,7 @@ export class AppImManager { @@ -645,7 +654,7 @@ export class AppImManager {
appSidebarRight.fillProfileElements()
]).catch(err => {
this.log.error(err);
this.log.error('setPeer promises error:', err);
});
}
@ -1189,7 +1198,12 @@ export class AppImManager { @@ -1189,7 +1198,12 @@ export class AppImManager {
if(!result || !result.history) {
console.timeEnd('render history total');
return true;
}
}
// commented bot getProfile in getHistory!
if(!result.history/* .filter((id: number) => id > 0) */.length && !isBackLimit) {
this.scrolledAll = true;
}
//this.chatInner.innerHTML = '';

2
src/lib/appManagers/appMessagesIDsManager.ts

@ -30,7 +30,7 @@ export class AppMessagesIDsManager { @@ -30,7 +30,7 @@ export class AppMessagesIDsManager {
}
public getMessageLocalID(fullMsgID: number) {
if (!fullMsgID) {
if(!fullMsgID) {
return 0;
}
return fullMsgID % this.fullMsgIDModulus;

32
src/lib/appManagers/appMessagesManager.ts

@ -2418,7 +2418,7 @@ export class AppMessagesManager { @@ -2418,7 +2418,7 @@ export class AppMessagesManager {
// need be commented for read out messages
//if(newUnreadCount != 0 || !isOut) { // fix 16.11.2019 (maybe not)
console.warn(dT(), 'cnt', peerID, newUnreadCount);
console.warn(dT(), 'cnt', peerID, newUnreadCount, isOut, foundDialog, update, foundAffected);
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: newUnreadCount});
//}
@ -3068,7 +3068,7 @@ export class AppMessagesManager { @@ -3068,7 +3068,7 @@ export class AppMessagesManager {
public requestHistory(peerID: number, maxID: number, limit: number, offset = 0) {
var isChannel = AppPeersManager.isChannel(peerID);
console.trace('requestHistory', peerID, maxID, limit, offset);
//console.trace('requestHistory', peerID, maxID, limit, offset);
return MTProto.apiManager.invokeApi('messages.getHistory', {
peer: AppPeersManager.getInputPeerByID(peerID),
@ -3079,16 +3079,7 @@ export class AppMessagesManager { @@ -3079,16 +3079,7 @@ export class AppMessagesManager {
max_id: 0,
min_id: 0,
hash: 0
}/* {
peer: AppPeersManager.getInputPeerByID(peerID),
offset_id: offset,
offset_date: 0,
add_offset: offset || 0,
limit: limit || 0,
max_id: maxID,
min_id: 0,
hash: 0
} */, {
}, {
timeout: 300,
noErrorBox: true
}).then((historyResult: any) => {
@ -3101,22 +3092,19 @@ export class AppMessagesManager { @@ -3101,22 +3092,19 @@ export class AppMessagesManager {
}
var length = historyResult.messages.length;
if(length &&
historyResult.messages[length - 1].deleted) {
if(length && historyResult.messages[length - 1].deleted) {
historyResult.messages.splice(length - 1, 1);
length--;
historyResult.count--;
}
if(
peerID < 0 ||
!appUsersManager.isBot(peerID) ||
(length == limit && limit < historyResult.count)
) {
// don't need the intro now
/* if(peerID < 0 || !appUsersManager.isBot(peerID) || (length == limit && limit < historyResult.count)) {
return historyResult;
}
} */
return historyResult;
return appProfileManager.getProfile(peerID).then((userFull: any) => {
/* return appProfileManager.getProfile(peerID).then((userFull: any) => {
var description = userFull.bot_info && userFull.bot_info.description;
if(description) {
var messageID = this.tempID--;
@ -3142,7 +3130,7 @@ export class AppMessagesManager { @@ -3142,7 +3130,7 @@ export class AppMessagesManager {
}
return historyResult;
});
}); */
}, (error) => {
switch (error.type) {
case 'CHANNEL_PRIVATE':

142
src/lib/appManagers/appSidebarLeft.ts

@ -1,10 +1,9 @@ @@ -1,10 +1,9 @@
import { logger } from "../polyfill";
import { scrollable } from "../../components/misc";
import { scrollable, putPreloader } from "../../components/misc";
import appMessagesManager from "./appMessagesManager";
import appDialogsManager from "./appDialogsManager";
import { isElementInViewport, $rootScope } from "../utils";
import { isElementInViewport } from "../utils";
import appMessagesIDsManager from "./appMessagesIDsManager";
import apiManager from '../mtproto/apiManager';
import appImManager from "./appImManager";
class AppSidebarLeft {
@ -12,13 +11,22 @@ class AppSidebarLeft { @@ -12,13 +11,22 @@ class AppSidebarLeft {
private searchInput = document.getElementById('global-search') as HTMLInputElement;
private toolsBtn = this.sidebarEl.querySelector('.sidebar-tools-button') as HTMLButtonElement;
private searchContainer = this.sidebarEl.querySelector('#search-container') as HTMLDivElement;
private menuEl = this.toolsBtn.querySelector('.btn-menu');
private savedBtn = this.menuEl.querySelector('.menu-saved');
private listsContainer: HTMLDivElement = null;
private searchMessagesList: HTMLUListElement = null;
private chatsContainer = document.getElementById('chats-container') as HTMLDivElement;
private chatsOffsetIndex = 0;
private chatsScroll: HTMLDivElement;
private chatsHidden: any;
private chatsPreloader: HTMLDivElement;
private chatsLoadCount = 0;
private loadDialogsPromise: Promise<any>;
private hiddenScroll: any;
private log = logger('SL');
private peerID = 0;
@ -29,31 +37,43 @@ class AppSidebarLeft { @@ -29,31 +37,43 @@ class AppSidebarLeft {
private searchPromise: Promise<void> = null;
private searchTimeout: number = 0;
private query = '';
public myID = 0;
private query = '';
constructor() {
this.listsContainer = scrollable(this.searchContainer);
this.searchMessagesList = document.createElement('ul');
apiManager.getUserID().then((id) => {
this.myID = id;
});
$rootScope.$on('user_auth', (e: CustomEvent) => {
let userAuth = e.detail;
this.myID = userAuth ? userAuth.id : 0;
});
this.chatsPreloader = document.createElement('div');
this.chatsPreloader.classList.add('preloader');
putPreloader(this.chatsPreloader);
this.chatsContainer.append(this.chatsPreloader);
this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
let {container: chatsScroll, hiddenElements: chatsHidden, onScroll: hiddenScroll} = scrollable(this.chatsContainer as HTMLDivElement);
this.chatsScroll = chatsScroll;
this.chatsHidden = chatsHidden;
this.hiddenScroll = hiddenScroll;
appDialogsManager.chatsHidden = this.chatsHidden;
chatsScroll.addEventListener('scroll', this.onChatsScroll.bind(this));
this.listsContainer = scrollable(this.searchContainer).container;
this.searchMessagesList = document.createElement('ul');
this.savedBtn.addEventListener('click', () => {
appImManager.setPeer(this.myID);
appImManager.setPeer(appImManager.myID);
});
/* this.listsContainer.insertBefore(this.searchMessagesList, this.listsContainer.lastElementChild);
for(let i = 0; i < 25; ++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);
} */
this.listsContainer.addEventListener('scroll', this.onSidebarScroll.bind(this));
this.searchContainer.append(this.listsContainer);
//this.searchContainer.append(this.listsContainer);
appDialogsManager.setListClickListener(this.searchMessagesList);
@ -85,13 +105,13 @@ class AppSidebarLeft { @@ -85,13 +105,13 @@ class AppSidebarLeft {
this.log('input', value);
if(this.listsContainer.contains(this.searchMessagesList)) {
this.listsContainer.removeChild(this.searchMessagesList)
this.listsContainer.removeChild(this.searchMessagesList);
}
if(!value.trim()) {
return;
}
this.query = value;
this.minMsgID = 0;
this.loadedCount = 0;
@ -113,18 +133,70 @@ class AppSidebarLeft { @@ -113,18 +133,70 @@ class AppSidebarLeft {
this.peerID = 0;
}
});
window.addEventListener('resize', () => {
setTimeout(() => this.onSidebarScroll(), 0);
this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
setTimeout(() => {
this.onSidebarScroll();
this.onChatsScroll();
}, 0);
});
}
public async loadDialogs() {
if(this.loadDialogsPromise/* || 1 == 1 */) return this.loadDialogsPromise;
this.chatsContainer.append(this.chatsPreloader);
//let offset = appMessagesManager.generateDialogIndex();/* appMessagesManager.dialogsNum */;
try {
this.loadDialogsPromise = appMessagesManager.getConversations('', this.chatsOffsetIndex, this.chatsLoadCount);
let result = await this.loadDialogsPromise;
if(result && result.dialogs && result.dialogs.length) {
this.chatsOffsetIndex = result.dialogs[result.dialogs.length - 1].index;
result.dialogs.forEach((dialog: any) => {
appDialogsManager.addDialog(dialog);
});
}
this.log('loaded ' + this.chatsLoadCount + ' dialogs by offset:', this.chatsOffsetIndex, result, this.chatsHidden);
this.hiddenScroll();
} catch(err) {
this.log.error(err);
}
this.chatsPreloader.remove();
this.loadDialogsPromise = undefined;
}
public onChatsScroll() {
if(this.chatsHidden.down.length > 0/* || 1 == 1 */) return;
if(!this.loadDialogsPromise) {
let d = Array.from(appDialogsManager.chatList.childNodes).slice(-5);
for(let node of d) {
if(isElementInViewport(node)) {
this.loadDialogs();
break;
}
}
//console.log('last 5 dialogs:', d);
}
}
public onSidebarScroll() {
if(!this.query.trim()) return;
let elements = Array.from(this.searchMessagesList.childNodes).slice(-5);
for(let li of elements) {
if(isElementInViewport(li)) {
this.log('Will load more search');
if(!this.searchTimeout) {
this.searchTimeout = setTimeout(() => {
this.searchMore();
@ -144,21 +216,23 @@ class AppSidebarLeft { @@ -144,21 +216,23 @@ class AppSidebarLeft {
this.searchInput.focus();
}
private searchMore() {
if(this.searchPromise) return this.searchPromise;
let query = this.query;
if(!query.trim()) return;
if(this.loadedCount != 0 && this.loadedCount >= this.foundCount) {
return Promise.resolve();
}
let maxID = appMessagesIDsManager.getMessageIDInfo(this.minMsgID)[0];
return this.searchPromise = appMessagesManager.getSearch(this.peerID, query, null, maxID, 20, this.offsetRate).then(res => {
this.searchPromise = null;
if(this.searchInput.value != query) {
return;
}
@ -166,7 +240,7 @@ class AppSidebarLeft { @@ -166,7 +240,7 @@ class AppSidebarLeft {
this.log('input search result:', this.peerID, query, null, maxID, 20, res);
let {count, history, next_rate} = res;
if(history[0] == this.minMsgID) {
history.shift();
}
@ -177,7 +251,7 @@ class AppSidebarLeft { @@ -177,7 +251,7 @@ class AppSidebarLeft {
if(!originalDialog) {
this.log('no original dialog by message:', message);
originalDialog = {
peerID: message.peerID,
pFlags: {},
@ -188,11 +262,11 @@ class AppSidebarLeft { @@ -188,11 +262,11 @@ class AppSidebarLeft {
let {dialog, dom} = appDialogsManager.addDialog(originalDialog, this.searchMessagesList, false);
appDialogsManager.setLastMessage(dialog, message, dom);
});
this.minMsgID = history[history.length - 1];
this.offsetRate = next_rate;
this.loadedCount += history.length;
if(!this.foundCount) {
this.foundCount = count;
}

43
src/lib/appManagers/appSidebarRight.ts

@ -65,6 +65,8 @@ class AppSidebarRight { @@ -65,6 +65,8 @@ class AppSidebarRight {
private log = logger('SR');
private peerID = 0;
constructor() {
let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement;
let tabs = this.profileContentEl.querySelector('.profile-tabs') as HTMLUListElement;
@ -143,7 +145,7 @@ class AppSidebarRight { @@ -143,7 +145,7 @@ class AppSidebarRight {
}
public loadSidebarMedia(single = false) {
let peerID = $rootScope.selectedPeerID;
let peerID = this.peerID;
let typesToLoad = single ? [this.sharedMediaType] : this.sharedMediaTypes;
@ -164,14 +166,14 @@ class AppSidebarRight { @@ -164,14 +166,14 @@ class AppSidebarRight {
? appMessagesManager.historiesStorage[peerID].history.slice() : [];
maxID = !maxID && ids.length ? ids[ids.length - 1] : maxID;
this.log('search house of glass pre', type, ids, maxID);
//this.log('search house of glass pre', type, ids, maxID);
return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, 50)
.then(value => {
ids = ids.concat(value.history);
history.push(...ids);
this.log('search house of glass', type, value, ids, this.cleared);
//this.log('search house of glass', type, value, ids, this.cleared);
if($rootScope.selectedPeerID != peerID) {
this.log.warn('peer changed');
@ -188,11 +190,11 @@ class AppSidebarRight { @@ -188,11 +190,11 @@ class AppSidebarRight {
let message = appMessagesManager.getMessage(mid);
if(!message.media) return;
/* 'inputMessagesFilterContacts',
'inputMessagesFilterPhotoVideo',
'inputMessagesFilterDocument',
'inputMessagesFilterUrl',
'inputMessagesFilterVoice'*/
/*'inputMessagesFilterContacts',
'inputMessagesFilterPhotoVideo',
'inputMessagesFilterDocument',
'inputMessagesFilterUrl',
'inputMessagesFilterVoice'*/
switch(type) {
case 'inputMessagesFilterPhotoVideo': {
/* if(!(message.media.photo || message.media.document || message.media.webpage.document)) {
@ -281,7 +283,8 @@ class AppSidebarRight { @@ -281,7 +283,8 @@ class AppSidebarRight {
}
public fillProfileElements() {
let peerID = $rootScope.selectedPeerID;
let peerID = this.peerID = $rootScope.selectedPeerID;
this.loadSidebarMediaPromises = {};
this.profileContentEl.parentElement.scrollTop = 0;
this.profileElements.bio.style.display = 'none';
@ -311,19 +314,19 @@ class AppSidebarRight { @@ -311,19 +314,19 @@ class AppSidebarRight {
};
// username
let username = appPeersManager.getPeerUsername($rootScope.selectedPeerID);
let username = appPeersManager.getPeerUsername(peerID);
if(username) {
setText(appPeersManager.getPeerUsername($rootScope.selectedPeerID), this.profileElements.username);
setText(appPeersManager.getPeerUsername(peerID), this.profileElements.username);
}
if($rootScope.selectedPeerID > 0) {
let user = appUsersManager.getUser($rootScope.selectedPeerID);
if(peerID > 0) {
let user = appUsersManager.getUser(peerID);
if(user.phone) {
setText('+' + formatPhoneNumber(user.phone).formatted, this.profileElements.phone);
}
appProfileManager.getProfile($rootScope.selectedPeerID, true).then(userFull => {
if($rootScope.selectedPeerID != peerID) {
appProfileManager.getProfile(peerID, true).then(userFull => {
if(this.peerID != peerID) {
this.log.warn('peer changed');
return;
}
@ -340,10 +343,10 @@ class AppSidebarRight { @@ -340,10 +343,10 @@ class AppSidebarRight {
}
});
} else {
let chat = appPeersManager.getPeer($rootScope.selectedPeerID);
let chat = appPeersManager.getPeer(peerID);
appProfileManager.getChatFull(chat.id).then((chatFull: any) => {
if($rootScope.selectedPeerID != peerID) {
if(this.peerID != peerID) {
this.log.warn('peer changed');
return;
}
@ -356,7 +359,7 @@ class AppSidebarRight { @@ -356,7 +359,7 @@ class AppSidebarRight {
});
}
let dialog: any = appMessagesManager.getDialogByPeerID($rootScope.selectedPeerID);
let dialog: any = appMessagesManager.getDialogByPeerID(peerID);
if(dialog.length) {
dialog = dialog[0];
let muted = false;
@ -368,8 +371,8 @@ class AppSidebarRight { @@ -368,8 +371,8 @@ class AppSidebarRight {
}
}
if($rootScope.selectedPeerID < 0) { // not human
let isChannel = appPeersManager.isChannel($rootScope.selectedPeerID) && !appPeersManager.isMegagroup($rootScope.selectedPeerID);
if(peerID < 0) { // not human
let isChannel = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID);
if(isChannel) {
appImManager.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
appImManager.btnMute.classList.add(muted ? 'tgico-unmute' : 'tgico-mute');

41
src/scss/materialize.scss vendored

@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
@charset "UTF-8";
// Color
@import "components/color-variables";
@import "components/color-classes";
// Variables;
@import "components/variables";
// Reset
@import "components/normalize";
// components
@import "components/global";
@import "components/badges";
@import "components/icons-material-design";
@import "components/grid";
@import "components/navbar";
@import "components/typography";
@import "components/transitions";
@import "components/cards";
@import "components/toast";
@import "components/tabs";
@import "components/tooltip";
@import "components/buttons";
@import "components/dropdown";
@import "components/waves";
@import "components/modal";
@import "components/collapsible";
@import "components/chips";
@import "components/materialbox";
@import "components/forms/forms";
@import "components/table_of_contents";
@import "components/sidenav";
@import "components/preloader";
@import "components/slider";
@import "components/carousel";
@import "components/tapTarget";
@import "components/pulse";
@import "components/datepicker";
@import "components/timepicker";

7
src/scss/partials/_leftSidebar.scss

@ -5,9 +5,14 @@ @@ -5,9 +5,14 @@
.sidebar-content {
width: 100%;
max-height: 100%;
height: 100%;
overflow: hidden;
display: flex; /* idk why but need */
position: relative;
> div {
width: 100%;
}
}
#chats-container {
@ -29,7 +34,7 @@ @@ -29,7 +34,7 @@
background: #fff;
&.active {
display: block;
display: flex;
}
}
}

Loading…
Cancel
Save