Browse Source

Search chats by latinize map

Fix contacts load on folder included chats
master
Eduard Kuzmenko 4 years ago
parent
commit
2e5ca96c14
  1. 114
      src/components/appSearch.ts
  2. 3
      src/components/sidebarLeft/tabs/includedChats.ts
  3. 8
      src/lib/appManagers/appChatsManager.ts
  4. 1
      src/lib/appManagers/appDialogsManager.ts
  5. 77
      src/lib/appManagers/appUsersManager.ts

114
src/components/appSearch.ts

@ -10,6 +10,7 @@ import SearchInput from "./searchInput";
import { Peer } from "../layer"; import { Peer } from "../layer";
import rootScope from "../lib/rootScope"; import rootScope from "../lib/rootScope";
import { escapeRegExp } from "../helpers/string"; import { escapeRegExp } from "../helpers/string";
import searchIndexManager from "../lib/searchIndexManager";
export class SearchGroup { export class SearchGroup {
container: HTMLDivElement; container: HTMLDivElement;
@ -143,13 +144,6 @@ export default class AppSearch {
this.searchInput.input.focus(); 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() { public searchMore() {
if(this.searchPromise) return this.searchPromise; if(this.searchPromise) return this.searchPromise;
@ -167,64 +161,32 @@ export default class AppSearch {
const maxID = appMessagesIDsManager.getMessageIDInfo(this.minMsgID)[0] || 0; const maxID = appMessagesIDsManager.getMessageIDInfo(this.minMsgID)[0] || 0;
if(!this.peerID && !maxID && !this.loadedContacts) { if(!this.peerID && !maxID && !this.loadedContacts) {
let renderedSaved = false; const renderedPeerIDs: Set<number> = new Set();
if('saved messages'.includes(query.toLowerCase())
|| appUsersManager.getUser(rootScope.myID).sortName.includes(query.toLowerCase())/* && this.searchGroups.hasOwnProperty('saved') */) {
this.renderSaved();
renderedSaved = true;
}
appUsersManager.searchContacts(query, 20).then((contacts) => { const setResults = (results: number[], group: SearchGroup, showMembersCount = false) => {
if(this.searchInput.value != query) { results.forEach((peerID) => {
if(renderedPeerIDs.has(peerID)) {
return; 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);
}
//console.log('input search contacts result:', contacts); const peer = appPeersManager.getPeer(peerID);
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();
}
return;
}
let peer = appPeersManager.getPeer(peerID);
let originalDialog = appMessagesManager.getDialogByPeerID(peerID)[0];
//////////this.log('contacts peer', peer); //////////this.log('contacts peer', peer);
if(!originalDialog) { const {dom} = appDialogsManager.addDialog(peerID, group.list, false);
/////////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);
if(showMembersCount && (peer.participants_count || peer.participants)) { if(showMembersCount && (peer.participants_count || peer.participants)) {
let regExp = new RegExp(`(${escapeRegExp(query)})`, 'gi'); const regExp = new RegExp(`(${escapeRegExp(query)}|${escapeRegExp(searchIndexManager.cleanSearchText(query))})`, 'gi');
dom.titleSpan.innerHTML = dom.titleSpan.innerHTML.replace(regExp, '<i>$1</i>'); dom.titleSpan.innerHTML = dom.titleSpan.innerHTML.replace(regExp, '<i>$1</i>');
dom.lastMessageSpan.innerText = appChatsManager.getChatMembersString(-peerID); dom.lastMessageSpan.innerText = appChatsManager.getChatMembersString(-peerID);
} else if(peerID == rootScope.myID) {
dom.lastMessageSpan.innerHTML = 'chat with yourself';
} else { } else {
let username = appPeersManager.getPeerUsername(peerID); let username = appPeersManager.getPeerUsername(peerID);
if(!username) { if(!username) {
let user = appUsersManager.getUser(peerID); const user = appUsersManager.getUser(peerID);
if(user && user.phone) { if(user && user.phone) {
username = '+' + formatPhoneNumber(user.phone).formatted; username = '+' + formatPhoneNumber(user.phone).formatted;
} }
@ -236,16 +198,42 @@ export default class AppSearch {
} }
}); });
if(results.length) group.setActive(); group.toggle();
else if(renderedSaved) { // удалить все пункты снизу };
Array.from(group.list.children).slice(1).forEach(c => c.remove());
} else { const onLoad = <T>(arg: T) => {
group.clear(); if(this.searchInput.value != query) {
return;
} }
this.loadedContacts = true;
return arg;
}; };
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.my_results, this.searchGroups.contacts, true);
setResults(contacts.results, this.searchGroups.globalContacts); 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,26 +253,16 @@ export default class AppSearch {
} }
const searchGroup = this.searchGroups.messages; const searchGroup = this.searchGroups.messages;
searchGroup.setActive();
history.forEach((msgID: number) => { history.forEach((msgID: number) => {
const message = appMessagesManager.getMessage(msgID); const message = appMessagesManager.getMessage(msgID);
let originalDialog = appMessagesManager.getDialogByPeerID(message.peerID)[0];
if(!originalDialog) { const {dialog, dom} = appDialogsManager.addDialog(message.peerID, this.scrollable/* searchGroup.list */, false);
////////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);
appDialogsManager.setLastMessage(dialog, message, dom, query); appDialogsManager.setLastMessage(dialog, message, dom, query);
}); });
searchGroup.toggle();
this.minMsgID = history[history.length - 1]; this.minMsgID = history[history.length - 1];
this.offsetRate = next_rate; this.offsetRate = next_rate;

3
src/components/sidebarLeft/tabs/includedChats.ts

@ -94,9 +94,10 @@ export default class AppIncludedChatsTab implements SliderTab {
return `<div class="checkbox"><label><input type="checkbox" ${selected ? 'checked' : ''}><span></span></label></div>`; return `<div class="checkbox"><label><input type="checkbox" ${selected ? 'checked' : ''}><span></span></label></div>`;
} }
renderResults = (peerIDs: number[]) => { renderResults = async(peerIDs: number[]) => {
//const other = this.type == 'included' ? this.filter.exclude_peers : this.filter.include_peers; //const other = this.type == 'included' ? this.filter.exclude_peers : this.filter.include_peers;
await appUsersManager.getContacts();
peerIDs.forEach(peerID => { peerIDs.forEach(peerID => {
//if(other.includes(peerID)) return; //if(other.includes(peerID)) return;

8
src/lib/appManagers/appChatsManager.ts

@ -392,8 +392,8 @@ export class AppChatsManager {
public createChannel(title: string, about: string): Promise<number> { public createChannel(title: string, about: string): Promise<number> {
return apiManager.invokeApi('channels.createChannel', { return apiManager.invokeApi('channels.createChannel', {
broadcast: true, broadcast: true,
title: title, title,
about: about about
}).then((updates: any) => { }).then((updates: any) => {
apiUpdatesManager.processUpdateMessage(updates); apiUpdatesManager.processUpdateMessage(updates);
@ -416,7 +416,7 @@ export class AppChatsManager {
public createChat(title: string, userIDs: number[]): Promise<number> { public createChat(title: string, userIDs: number[]): Promise<number> {
return apiManager.invokeApi('messages.createChat', { return apiManager.invokeApi('messages.createChat', {
users: userIDs.map(u => appUsersManager.getUserInput(u)), users: userIDs.map(u => appUsersManager.getUserInput(u)),
title: title title
}).then(updates => { }).then(updates => {
apiUpdatesManager.processUpdateMessage(updates); apiUpdatesManager.processUpdateMessage(updates);
@ -489,7 +489,7 @@ export class AppChatsManager {
} }
private onChatUpdated = (chatID: number, updates: any) => { private onChatUpdated = (chatID: number, updates: any) => {
console.log('onChatUpdated', chatID, updates); //console.log('onChatUpdated', chatID, updates);
apiUpdatesManager.processUpdateMessage(updates); apiUpdatesManager.processUpdateMessage(updates);
if(updates && if(updates &&

1
src/lib/appManagers/appDialogsManager.ts

@ -1104,6 +1104,7 @@ export class AppDialogsManager {
if(!originalDialog) { if(!originalDialog) {
originalDialog = { originalDialog = {
peerID: _dialog, peerID: _dialog,
peer: appPeersManager.getOutputPeer(_dialog),
pFlags: {} pFlags: {}
} as any; } as any;
} }

77
src/lib/appManagers/appUsersManager.ts

@ -19,16 +19,16 @@ import appStateManager from "./appStateManager";
export type User = MTUser.user; export type User = MTUser.user;
export class AppUsersManager { export class AppUsersManager {
public users: {[userID: number]: User} = {}; private users: {[userID: number]: User} = {};
public usernames: {[username: string]: number} = {}; private usernames: {[username: string]: number} = {};
//public userAccess: {[userID: number]: string} = {}; //public userAccess: {[userID: number]: string} = {};
public cachedPhotoLocations: any = {}; private cachedPhotoLocations: any = {};
public contactsIndex = searchIndexManager.createIndex(); private contactsIndex = searchIndexManager.createIndex();
public contactsFillPromise: Promise<Set<number>>; private contactsFillPromise: Promise<Set<number>>;
public contactsList: Set<number> = new Set(); public contactsList: Set<number> = new Set();
private updatedContactsList = false; private updatedContactsList = false;
public getTopPeersPromise: Promise<number[]>; private getTopPeersPromise: Promise<number[]>;
constructor() { constructor() {
setInterval(this.updateUsersStatuses, 60000); setInterval(this.updateUsersStatuses, 60000);
@ -110,6 +110,8 @@ export class AppUsersManager {
}); });
appStateManager.getState().then((state) => { appStateManager.getState().then((state) => {
this.users = state.users;
const contactsList = state.contactsList; const contactsList = state.contactsList;
if(contactsList && Array.isArray(contactsList)) { if(contactsList && Array.isArray(contactsList)) {
contactsList.forEach(userID => { contactsList.forEach(userID => {
@ -118,8 +120,6 @@ export class AppUsersManager {
this.contactsFillPromise = Promise.resolve(this.contactsList); this.contactsFillPromise = Promise.resolve(this.contactsList);
} }
this.users = state.users;
}); });
} }
@ -179,7 +179,7 @@ export class AppUsersManager {
' ' + serviceText; ' ' + serviceText;
} }
public getContacts(query?: string) { public getContacts(query?: string, includeSaved = false) {
return this.fillContacts().then(_contactsList => { return this.fillContacts().then(_contactsList => {
let contactsList = [..._contactsList]; let contactsList = [..._contactsList];
if(query) { if(query) {
@ -196,6 +196,16 @@ export class AppUsersManager {
return sortName1.localeCompare(sortName2); 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) => { /* contactsList.sort((userID1: number, userID2: number) => {
const sortName1 = (this.users[userID1] || {}).sortName || ''; const sortName1 = (this.users[userID1] || {}).sortName || '';
const sortName2 = (this.users[userID2] || {}).sortName || ''; const sortName2 = (this.users[userID2] || {}).sortName || '';
@ -222,15 +232,14 @@ export class AppUsersManager {
return; return;
} }
var userID = user.id; const userID = user.id;
var result = this.users[userID];
if(user.pFlags === undefined) { if(user.pFlags === undefined) {
user.pFlags = {}; user.pFlags = {};
} }
if(user.pFlags.min) { if(user.pFlags.min) {
if(result !== undefined) { if(this.users[userID] !== undefined) {
return; return;
} }
} }
@ -252,7 +261,7 @@ export class AppUsersManager {
} }
if(user.username) { if(user.username) {
var searchUsername = searchIndexManager.cleanUsername(user.username); const searchUsername = searchIndexManager.cleanUsername(user.username);
this.usernames[searchUsername] = userID; this.usernames[searchUsername] = userID;
} }
@ -276,11 +285,11 @@ export class AppUsersManager {
user.sortStatus = this.getUserStatusForSort(user.status); user.sortStatus = this.getUserStatusForSort(user.status);
} }
var result = this.users[userID]; const oldUser = this.users[userID];
if(result === undefined) { if(oldUser === undefined) {
result = this.users[userID] = user; this.users[userID] = user;
} else { } else {
safeReplaceObject(result, user); safeReplaceObject(oldUser, user);
} }
rootScope.broadcast('user_update', userID); 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) { public searchContacts(query: string, limit = 20) {
return apiManager.invokeApi('contacts.search', { return apiManager.invokeApi('contacts.search', {
q: query, q: query,
limit limit
}).then((peers) => { }).then(peers => {
//console.log('search contacts result:', peers);
this.saveApiUsers(peers.users); this.saveApiUsers(peers.users);
appChatsManager.saveApiChats(peers.chats); 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;
}); });
} }

Loading…
Cancel
Save