From 2e5ca96c140258df64cb1cf36ce689da467f23cc Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Thu, 19 Nov 2020 08:09:45 +0200 Subject: [PATCH] Search chats by latinize map Fix contacts load on folder included chats --- src/components/appSearch.ts | 154 ++++++++---------- .../sidebarLeft/tabs/includedChats.ts | 3 +- src/lib/appManagers/appChatsManager.ts | 8 +- src/lib/appManagers/appDialogsManager.ts | 1 + src/lib/appManagers/appUsersManager.ts | 77 ++++++--- 5 files changed, 130 insertions(+), 113 deletions(-) diff --git a/src/components/appSearch.ts b/src/components/appSearch.ts index 134a089f..e050f821 100644 --- a/src/components/appSearch.ts +++ b/src/components/appSearch.ts @@ -10,6 +10,7 @@ import SearchInput from "./searchInput"; import { Peer } from "../layer"; import rootScope from "../lib/rootScope"; import { escapeRegExp } from "../helpers/string"; +import searchIndexManager from "../lib/searchIndexManager"; export class SearchGroup { container: HTMLDivElement; @@ -143,13 +144,6 @@ export default class AppSearch { this.searchInput.input.focus(); } - private renderSaved() { - const group = this.searchGroups.contacts; - let {dialog, dom} = appDialogsManager.addDialog(rootScope.myID, group.list, false); - dom.lastMessageSpan.innerHTML = 'chat with yourself'; - group.setActive(); - } - public searchMore() { if(this.searchPromise) return this.searchPromise; @@ -167,85 +161,79 @@ export default class AppSearch { const maxID = appMessagesIDsManager.getMessageIDInfo(this.minMsgID)[0] || 0; if(!this.peerID && !maxID && !this.loadedContacts) { - let renderedSaved = false; - if('saved messages'.includes(query.toLowerCase()) - || appUsersManager.getUser(rootScope.myID).sortName.includes(query.toLowerCase())/* && this.searchGroups.hasOwnProperty('saved') */) { - this.renderSaved(); - renderedSaved = true; - } + const renderedPeerIDs: Set = new Set(); - appUsersManager.searchContacts(query, 20).then((contacts) => { - if(this.searchInput.value != query) { - return; - } + const setResults = (results: number[], group: SearchGroup, showMembersCount = false) => { + results.forEach((peerID) => { + if(renderedPeerIDs.has(peerID)) { + return; + } - this.loadedContacts = true; + renderedPeerIDs.add(peerID); - // set saved message as first peer to render - const peer = contacts.my_results.findAndSplice(p => (p as Peer.peerUser).user_id == rootScope.myID); - if(peer) { - contacts.my_results.unshift(peer); - } + const peer = appPeersManager.getPeer(peerID); - //console.log('input search contacts result:', contacts); + //////////this.log('contacts peer', peer); - let setResults = (results: Peer[], group: SearchGroup, showMembersCount = false) => { - // ! because contacts.search returns duplicates in my_results - new Set(results.map(peer => appPeersManager.getPeerID(peer))).forEach((peerID) => { - if(peerID == rootScope.myID) { - if(!renderedSaved) { - this.renderSaved(); - } + const {dom} = appDialogsManager.addDialog(peerID, group.list, false); - return; + if(showMembersCount && (peer.participants_count || peer.participants)) { + const regExp = new RegExp(`(${escapeRegExp(query)}|${escapeRegExp(searchIndexManager.cleanSearchText(query))})`, 'gi'); + dom.titleSpan.innerHTML = dom.titleSpan.innerHTML.replace(regExp, '$1'); + dom.lastMessageSpan.innerText = appChatsManager.getChatMembersString(-peerID); + } else if(peerID == rootScope.myID) { + dom.lastMessageSpan.innerHTML = 'chat with yourself'; + } else { + let username = appPeersManager.getPeerUsername(peerID); + if(!username) { + const user = appUsersManager.getUser(peerID); + if(user && user.phone) { + username = '+' + formatPhoneNumber(user.phone).formatted; + } + } else { + username = '@' + username; } - let peer = appPeersManager.getPeer(peerID); - let originalDialog = appMessagesManager.getDialogByPeerID(peerID)[0]; - - //////////this.log('contacts peer', peer); - - if(!originalDialog) { - /////////this.log('no original dialog by peerID:', peerID); - - originalDialog = { - peerID: peerID, - pFlags: {}, - peer: peer - } as any; - } - - let {dialog, dom} = appDialogsManager.addDialog(originalDialog, group.list, false); + dom.lastMessageSpan.innerHTML = '' + username + ''; + } + }); - if(showMembersCount && (peer.participants_count || peer.participants)) { - let regExp = new RegExp(`(${escapeRegExp(query)})`, 'gi'); - dom.titleSpan.innerHTML = dom.titleSpan.innerHTML.replace(regExp, '$1'); - dom.lastMessageSpan.innerText = appChatsManager.getChatMembersString(-peerID); - } 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; - } + group.toggle(); + }; - dom.lastMessageSpan.innerHTML = '' + username + ''; - } - }); + const onLoad = (arg: T) => { + if(this.searchInput.value != query) { + return; + } - if(results.length) group.setActive(); - else if(renderedSaved) { // удалить все пункты снизу - Array.from(group.list.children).slice(1).forEach(c => c.remove()); - } else { - group.clear(); - } - }; + this.loadedContacts = true; + + return arg; + }; - setResults(contacts.my_results, this.searchGroups.contacts, true); - setResults(contacts.results, this.searchGroups.globalContacts); + appUsersManager.getContacts(query, true) + .then(onLoad) + .then((contacts) => { + if(contacts) { + setResults(contacts, this.searchGroups.contacts, true); + } + }); + + appUsersManager.searchContacts(query, 20) + .then(onLoad) + .then((contacts) => { + if(contacts) { + setResults(contacts.my_results, this.searchGroups.contacts, true); + setResults(contacts.results, this.searchGroups.globalContacts); + } + }); + + appMessagesManager.getConversations(query, 0, 20, 0) + .then(onLoad) + .then(value => { + if(value) { + setResults(value.dialogs.map(d => d.peerID), this.searchGroups.contacts, true); + } }); } @@ -265,25 +253,15 @@ export default class AppSearch { } const searchGroup = this.searchGroups.messages; - searchGroup.setActive(); history.forEach((msgID: number) => { const message = appMessagesManager.getMessage(msgID); - let originalDialog = appMessagesManager.getDialogByPeerID(message.peerID)[0]; - - if(!originalDialog) { - ////////this.log('no original dialog by message:', message); - - originalDialog = { - peerID: message.peerID, - pFlags: {}, - peer: message.peer_id - } as any; - } - - const {dialog, dom} = appDialogsManager.addDialog(originalDialog, this.scrollable/* searchGroup.list */, false); + + const {dialog, dom} = appDialogsManager.addDialog(message.peerID, this.scrollable/* searchGroup.list */, false); appDialogsManager.setLastMessage(dialog, message, dom, query); }); + + searchGroup.toggle(); this.minMsgID = history[history.length - 1]; this.offsetRate = next_rate; diff --git a/src/components/sidebarLeft/tabs/includedChats.ts b/src/components/sidebarLeft/tabs/includedChats.ts index b272d08d..b2456bfb 100644 --- a/src/components/sidebarLeft/tabs/includedChats.ts +++ b/src/components/sidebarLeft/tabs/includedChats.ts @@ -94,9 +94,10 @@ export default class AppIncludedChatsTab implements SliderTab { return `
`; } - renderResults = (peerIDs: number[]) => { + renderResults = async(peerIDs: number[]) => { //const other = this.type == 'included' ? this.filter.exclude_peers : this.filter.include_peers; + await appUsersManager.getContacts(); peerIDs.forEach(peerID => { //if(other.includes(peerID)) return; diff --git a/src/lib/appManagers/appChatsManager.ts b/src/lib/appManagers/appChatsManager.ts index ae9890a2..61ad82ba 100644 --- a/src/lib/appManagers/appChatsManager.ts +++ b/src/lib/appManagers/appChatsManager.ts @@ -392,8 +392,8 @@ export class AppChatsManager { public createChannel(title: string, about: string): Promise { return apiManager.invokeApi('channels.createChannel', { broadcast: true, - title: title, - about: about + title, + about }).then((updates: any) => { apiUpdatesManager.processUpdateMessage(updates); @@ -416,7 +416,7 @@ export class AppChatsManager { public createChat(title: string, userIDs: number[]): Promise { return apiManager.invokeApi('messages.createChat', { users: userIDs.map(u => appUsersManager.getUserInput(u)), - title: title + title }).then(updates => { apiUpdatesManager.processUpdateMessage(updates); @@ -489,7 +489,7 @@ export class AppChatsManager { } private onChatUpdated = (chatID: number, updates: any) => { - console.log('onChatUpdated', chatID, updates); + //console.log('onChatUpdated', chatID, updates); apiUpdatesManager.processUpdateMessage(updates); if(updates && diff --git a/src/lib/appManagers/appDialogsManager.ts b/src/lib/appManagers/appDialogsManager.ts index 230dcc3b..079f22c5 100644 --- a/src/lib/appManagers/appDialogsManager.ts +++ b/src/lib/appManagers/appDialogsManager.ts @@ -1104,6 +1104,7 @@ export class AppDialogsManager { if(!originalDialog) { originalDialog = { peerID: _dialog, + peer: appPeersManager.getOutputPeer(_dialog), pFlags: {} } as any; } diff --git a/src/lib/appManagers/appUsersManager.ts b/src/lib/appManagers/appUsersManager.ts index f594cfac..a05f834f 100644 --- a/src/lib/appManagers/appUsersManager.ts +++ b/src/lib/appManagers/appUsersManager.ts @@ -19,16 +19,16 @@ import appStateManager from "./appStateManager"; export type User = MTUser.user; export class AppUsersManager { - public users: {[userID: number]: User} = {}; - public usernames: {[username: string]: number} = {}; + private users: {[userID: number]: User} = {}; + private usernames: {[username: string]: number} = {}; //public userAccess: {[userID: number]: string} = {}; - public cachedPhotoLocations: any = {}; - public contactsIndex = searchIndexManager.createIndex(); - public contactsFillPromise: Promise>; + private cachedPhotoLocations: any = {}; + private contactsIndex = searchIndexManager.createIndex(); + private contactsFillPromise: Promise>; public contactsList: Set = new Set(); private updatedContactsList = false; - public getTopPeersPromise: Promise; + private getTopPeersPromise: Promise; constructor() { setInterval(this.updateUsersStatuses, 60000); @@ -110,6 +110,8 @@ export class AppUsersManager { }); appStateManager.getState().then((state) => { + this.users = state.users; + const contactsList = state.contactsList; if(contactsList && Array.isArray(contactsList)) { contactsList.forEach(userID => { @@ -118,8 +120,6 @@ export class AppUsersManager { this.contactsFillPromise = Promise.resolve(this.contactsList); } - - this.users = state.users; }); } @@ -179,7 +179,7 @@ export class AppUsersManager { ' ' + serviceText; } - public getContacts(query?: string) { + public getContacts(query?: string, includeSaved = false) { return this.fillContacts().then(_contactsList => { let contactsList = [..._contactsList]; if(query) { @@ -196,6 +196,16 @@ export class AppUsersManager { return sortName1.localeCompare(sortName2); }); + if(includeSaved) { + const isSearchingSaved = 'saved messages'.includes(query.toLowerCase()) + || appUsersManager.getUser(rootScope.myID).sortName.includes(query.toLowerCase()); + + if(isSearchingSaved) { + contactsList.findAndSplice(p => p == rootScope.myID); + contactsList.unshift(rootScope.myID); + } + } + /* contactsList.sort((userID1: number, userID2: number) => { const sortName1 = (this.users[userID1] || {}).sortName || ''; const sortName2 = (this.users[userID2] || {}).sortName || ''; @@ -222,15 +232,14 @@ export class AppUsersManager { return; } - var userID = user.id; - var result = this.users[userID]; + const userID = user.id; if(user.pFlags === undefined) { user.pFlags = {}; } if(user.pFlags.min) { - if(result !== undefined) { + if(this.users[userID] !== undefined) { return; } } @@ -252,7 +261,7 @@ export class AppUsersManager { } if(user.username) { - var searchUsername = searchIndexManager.cleanUsername(user.username); + const searchUsername = searchIndexManager.cleanUsername(user.username); this.usernames[searchUsername] = userID; } @@ -276,11 +285,11 @@ export class AppUsersManager { user.sortStatus = this.getUserStatusForSort(user.status); } - var result = this.users[userID]; - if(result === undefined) { - result = this.users[userID] = user; + const oldUser = this.users[userID]; + if(oldUser === undefined) { + this.users[userID] = user; } else { - safeReplaceObject(result, user); + safeReplaceObject(oldUser, user); } rootScope.broadcast('user_update', userID); @@ -599,16 +608,44 @@ export class AppUsersManager { }); } + /* public searchContacts(query: string, limit = 20) { + return Promise.all([ + this.getContacts(query), + apiManager.invokeApi('contacts.search', { + q: query, + limit + }) + ]).then(results => { + const [myContacts, peers] = results; + + this.saveApiUsers(peers.users); + appChatsManager.saveApiChats(peers.chats); + + // * contacts.search returns duplicates in my_results + const myResults = new Set(myContacts.concat(peers.my_results.map(p => appPeersManager.getPeerID(p)))); + + const out = { + my_results: [...myResults].slice(0, limit), + results: peers.results.map(p => appPeersManager.getPeerID(p)) + }; + + return out; + }); + } */ public searchContacts(query: string, limit = 20) { return apiManager.invokeApi('contacts.search', { q: query, limit - }).then((peers) => { - //console.log('search contacts result:', peers); + }).then(peers => { this.saveApiUsers(peers.users); appChatsManager.saveApiChats(peers.chats); - return peers; + const out = { + my_results: [...new Set(peers.my_results.map(p => appPeersManager.getPeerID(p)))], // ! contacts.search returns duplicates in my_results + results: peers.results.map(p => appPeersManager.getPeerID(p)) + }; + + return out; }); }