tweb-i2p/src/lib/appManagers/appSidebarLeft.ts

336 lines
11 KiB
TypeScript
Raw Normal View History

2020-02-06 22:43:07 +07:00
import { logger } from "../polyfill";
import { formatPhoneNumber } from "../../components/misc";
import Scrollable from '../../components/scrollable';
import appMessagesManager from "./appMessagesManager";
2020-02-06 22:43:07 +07:00
import appDialogsManager from "./appDialogsManager";
import { isElementInViewport, numberWithCommas, $rootScope } from "../utils";
2020-02-07 13:38:55 +07:00
import appMessagesIDsManager from "./appMessagesIDsManager";
import appImManager from "./appImManager";
import appUsersManager from "./appUsersManager";
import apiManager from "../mtproto/apiManager";
import appPeersManager from './appPeersManager';
2020-02-27 00:52:59 +07:00
class SearchGroup {
container: HTMLDivElement;
nameEl: HTMLDivElement;
list: HTMLUListElement;
constructor(public name: string, public type: string) {
this.list = document.createElement('ul');
this.container = document.createElement('div');
this.nameEl = document.createElement('div');
this.nameEl.classList.add('search-group__name');
this.nameEl.innerText = name;
this.container.classList.add('search-group');
this.container.append(this.nameEl, this.list);
this.container.style.display = 'none';
2020-04-08 18:46:43 +03:00
appDialogsManager.setListClickListener(this.list);
}
clear() {
this.container.style.display = 'none';
this.list.innerHTML = '';
}
setActive() {
this.container.style.display = '';
}
}
2020-02-06 22:43:07 +07:00
class AppSidebarLeft {
private sidebarEl = document.querySelector('.page-chats .chats-container') as HTMLDivElement;
private searchInput = document.getElementById('global-search') as HTMLInputElement;
private toolsBtn = this.sidebarEl.querySelector('.sidebar-tools-button') as HTMLButtonElement;
private backBtn = this.sidebarEl.querySelector('.sidebar-back-button') as HTMLButtonElement;
2020-02-06 22:43:07 +07:00
private searchContainer = this.sidebarEl.querySelector('#search-container') as HTMLDivElement;
2020-02-08 18:58:22 +07:00
private menuEl = this.toolsBtn.querySelector('.btn-menu');
private savedBtn = this.menuEl.querySelector('.menu-saved');
private archivedBtn = this.menuEl.querySelector('.menu-archive');
private logOutBtn = this.menuEl.querySelector('.menu-logout');
public archivedCount = this.archivedBtn.querySelector('.archived-count') as HTMLSpanElement;
2020-02-07 13:38:55 +07:00
2020-02-06 22:43:07 +07:00
private listsContainer: HTMLDivElement = null;
2020-02-07 13:38:55 +07:00
2020-02-06 22:43:07 +07:00
private log = logger('SL');
2020-02-07 13:38:55 +07:00
2020-02-06 22:43:07 +07:00
private peerID = 0;
2020-02-07 13:38:55 +07:00
private minMsgID = 0;
private loadedCount = 0;
private foundCount = 0;
private offsetRate = 0;
2020-02-06 22:43:07 +07:00
private searchPromise: Promise<void> = null;
2020-02-07 13:38:55 +07:00
private searchTimeout: number = 0;
2020-02-08 18:58:22 +07:00
private query = '';
public searchGroups: {[group: string]: SearchGroup} = {};
2020-02-21 15:25:19 +07:00
2020-02-06 22:43:07 +07:00
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')
};
this.listsContainer = new Scrollable(this.searchContainer).container;
for(let i in this.searchGroups) {
this.listsContainer.append(this.searchGroups[i].container);
}
2020-02-08 18:58:22 +07:00
2020-02-10 14:56:15 +07:00
this.savedBtn.addEventListener('click', (e) => {
2020-02-17 19:18:06 +07:00
///////this.log('savedbtn click');
2020-02-10 14:56:15 +07:00
setTimeout(() => { // menu doesn't close if no timeout (lol)
2020-02-13 22:42:39 +07:00
let dom = appDialogsManager.getDialogDom(appImManager.myID);
2020-04-08 18:46:43 +03:00
appImManager.setPeer(appImManager.myID);
2020-02-10 14:56:15 +07:00
}, 0);
});
2020-02-07 13:38:55 +07:00
this.archivedBtn.addEventListener('click', (e) => {
appDialogsManager.chatsArchivedContainer.classList.add('active');
this.toolsBtn.classList.remove('active');
this.backBtn.classList.add('active');
//this.toolsBtn.classList.remove('tgico-menu', 'btn-menu-toggle');
//this.toolsBtn.classList.add('tgico-back');
});
this.logOutBtn.addEventListener('click', (e) => {
apiManager.logOut();
});
this.listsContainer.addEventListener('scroll', this.onSidebarScroll.bind(this));
2020-02-22 18:20:43 +07:00
2020-02-06 22:43:07 +07:00
this.searchInput.addEventListener('focus', (e) => {
this.toolsBtn.classList.remove('active');
this.backBtn.classList.add('active');
2020-02-06 22:43:07 +07:00
this.searchContainer.classList.add('active');
2020-02-07 13:38:55 +07:00
2020-02-06 22:43:07 +07:00
if(!this.searchInput.value) {
for(let i in this.searchGroups) {
this.searchGroups[i].clear();
}
2020-02-06 22:43:07 +07:00
}
2020-02-09 17:30:24 +07:00
2020-02-06 22:43:07 +07:00
this.searchInput.addEventListener('blur', (e) => {
if(!this.searchInput.value) {
this.toolsBtn.classList.add('active');
this.backBtn.classList.remove('active');
2020-02-06 22:43:07 +07:00
this.searchContainer.classList.remove('active');
2020-02-17 19:18:06 +07:00
this.backBtn.click();
2020-02-06 22:43:07 +07:00
}
2020-02-07 13:38:55 +07:00
/* this.peerID = 0;
this.loadedCount = 0;
this.minMsgID = 0; */
2020-02-06 22:43:07 +07:00
}, {once: true});
});
2020-02-07 13:38:55 +07:00
2020-02-06 22:43:07 +07:00
this.searchInput.addEventListener('input', (e) => {
//console.log('messageInput input', this.innerText, serializeNodes(Array.from(messageInput.childNodes)));
let value = this.searchInput.value;
2020-02-17 19:18:06 +07:00
////////this.log('input', value);
2020-02-07 13:38:55 +07:00
2020-02-06 22:43:07 +07:00
if(!value.trim()) {
2020-02-17 19:18:06 +07:00
//this.peerID = 0;
2020-02-06 22:43:07 +07:00
return;
}
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
this.query = value;
this.minMsgID = 0;
this.loadedCount = 0;
this.foundCount = 0;
this.offsetRate = 0;
for(let i in this.searchGroups) {
this.searchGroups[i].clear();
}
2020-02-07 13:38:55 +07:00
this.searchPromise = null;
this.searchMore();
2020-02-06 22:43:07 +07:00
});
2020-02-10 14:56:15 +07:00
this.backBtn.addEventListener('click', (e) => {
appDialogsManager.chatsArchivedContainer.classList.remove('active');
this.toolsBtn.classList.add('active');
this.backBtn.classList.remove('active');
2020-02-17 19:18:06 +07:00
this.searchInput.value = '';
this.searchContainer.classList.remove('active');
this.peerID = 0;
});
2020-02-07 13:38:55 +07:00
window.addEventListener('resize', () => {
2020-02-27 00:52:59 +07:00
//this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
2020-02-08 18:58:22 +07:00
setTimeout(() => {
this.onSidebarScroll();
}, 0);
2020-02-07 13:38:55 +07:00
});
$rootScope.$on('dialogs_archived_unread', (e: CustomEvent) => {
this.archivedCount.innerText = '' + e.detail.count;
});
/* appUsersManager.getTopPeers().then(categories => {
this.log('got top categories:', categories);
}); */
2020-02-07 13:38:55 +07:00
}
public onSidebarScroll() {
2020-02-08 18:58:22 +07:00
if(!this.query.trim()) return;
let elements = Array.from(this.searchGroups[this.peerID ? 'privateMessages' : 'globalMessages'].list.childNodes).slice(-5);
2020-02-07 13:38:55 +07:00
for(let li of elements) {
if(isElementInViewport(li)) {
this.log('Will load more search');
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
if(!this.searchTimeout) {
this.searchTimeout = setTimeout(() => {
this.searchMore();
this.searchTimeout = 0;
}, 0);
}
break;
}
}
}
2020-02-06 22:43:07 +07:00
public beginSearch(peerID?: number) {
if(peerID) {
this.peerID = peerID;
}
2020-02-07 13:38:55 +07:00
2020-02-06 22:43:07 +07:00
this.searchInput.focus();
}
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
private searchMore() {
if(this.searchPromise) return this.searchPromise;
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
let query = this.query;
2020-02-08 18:58:22 +07:00
if(!query.trim()) return;
2020-02-07 13:38:55 +07:00
if(this.loadedCount != 0 && this.loadedCount >= this.foundCount) {
return Promise.resolve();
}
2020-02-07 14:39:00 +07:00
let maxID = appMessagesIDsManager.getMessageIDInfo(this.minMsgID)[0];
if(!this.peerID && !maxID) {
appUsersManager.searchContacts(query, 20).then((contacts: any) => {
if(this.searchInput.value != query) {
return;
}
2020-02-17 19:18:06 +07:00
///////this.log('input search contacts result:', contacts);
let setResults = (results: any, group: SearchGroup, showMembersCount = false) => {
results.forEach((inputPeer: any) => {
let peerID = appPeersManager.getPeerID(inputPeer);
let peer = appPeersManager.getPeer(peerID);
let originalDialog = appMessagesManager.getDialogByPeerID(peerID)[0];
2020-02-17 19:18:06 +07:00
//////////this.log('contacts peer', peer);
if(!originalDialog) {
2020-02-17 19:18:06 +07:00
/////////this.log('no original dialog by peerID:', peerID);
originalDialog = {
peerID: peerID,
pFlags: {},
peer: peer
};
}
let {dialog, dom} = appDialogsManager.addDialog(originalDialog, group.list, false);
if(showMembersCount && (peer.participants_count || peer.participants)) {
let isChannel = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID);
let participants_count = peer.participants_count || peer.participants.participants.length;
let subtitle = numberWithCommas(participants_count) + ' ' + (isChannel ? 'subscribers' : 'members');
dom.lastMessageSpan.innerText = subtitle;
} else {
let username = appPeersManager.getPeerUsername(peerID);
if(!username) {
let user = appUsersManager.getUser(peerID);
if(user && user.phone) {
username = '+' + formatPhoneNumber(user.phone).formatted;
}
} else {
username = '@' + username;
}
dom.lastMessageSpan.innerText = username;
}
});
if(results.length) {
group.setActive();
}
};
setResults(contacts.my_results, this.searchGroups.contacts, true);
setResults(contacts.results, this.searchGroups.globalContacts);
});
}
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
return this.searchPromise = appMessagesManager.getSearch(this.peerID, query, null, maxID, 20, this.offsetRate).then(res => {
this.searchPromise = null;
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
if(this.searchInput.value != query) {
return;
}
2020-02-17 19:18:06 +07:00
/////////this.log('input search result:', this.peerID, query, null, maxID, 20, res);
2020-02-07 13:38:55 +07:00
let {count, history, next_rate} = res;
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
if(history[0] == this.minMsgID) {
history.shift();
}
let searchGroup = this.searchGroups[this.peerID ? 'privateMessages' : 'globalMessages'];
searchGroup.setActive();
2020-02-07 13:38:55 +07:00
history.forEach((msgID: number) => {
let message = appMessagesManager.getMessage(msgID);
let originalDialog = appMessagesManager.getDialogByPeerID(message.peerID)[0];
if(!originalDialog) {
2020-02-17 19:18:06 +07:00
////////this.log('no original dialog by message:', message);
2020-02-08 18:58:22 +07:00
2020-02-07 14:39:00 +07:00
originalDialog = {
peerID: message.peerID,
pFlags: {},
peer: message.to_id
};
2020-02-07 13:38:55 +07:00
}
let {dialog, dom} = appDialogsManager.addDialog(originalDialog, searchGroup.list, false);
2020-02-07 13:38:55 +07:00
appDialogsManager.setLastMessage(dialog, message, dom);
});
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
this.minMsgID = history[history.length - 1];
this.offsetRate = next_rate;
this.loadedCount += history.length;
2020-02-08 18:58:22 +07:00
2020-02-07 13:38:55 +07:00
if(!this.foundCount) {
this.foundCount = count;
}
}).catch(err => {
this.log.error('search error', err);
this.searchPromise = null;
});
}
2020-02-06 22:43:07 +07:00
}
2020-04-08 18:46:43 +03:00
const appSidebarLeft = new AppSidebarLeft();
(window as any).appSidebarLeft = appSidebarLeft;
export default appSidebarLeft;