Browse Source

Allow global search in user pick popup

master
Eduard Kuzmenko 3 years ago
parent
commit
c2b1326bd8
  1. 124
      src/components/appSelectPeers.ts
  2. 4
      src/lib/appManagers/appUsersManager.ts
  3. 1
      src/scss/partials/popups/_forward.scss

124
src/components/appSelectPeers.ts

@ -21,6 +21,8 @@ import findUpClassName from "../helpers/dom/findUpClassName"; @@ -21,6 +21,8 @@ import findUpClassName from "../helpers/dom/findUpClassName";
import PeerTitle from "./peerTitle";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import replaceContent from "../helpers/dom/replaceContent";
import { filterUnique } from "../helpers/array";
import debounce from "../helpers/schedulers/debounce";
type PeerType = 'contacts' | 'dialogs' | 'channelParticipants';
@ -70,7 +72,9 @@ export default class AppSelectPeers { @@ -70,7 +72,9 @@ export default class AppSelectPeers {
private placeholder: LangPackKey;
private selfPresence: LangPackKey = 'Presence.YourChat';
private selfPresence: LangPackKey = 'Presence.YourChat'
private needSwitchList = false;
constructor(options: {
appendTo: AppSelectPeers['appendTo'],
@ -90,13 +94,12 @@ export default class AppSelectPeers { @@ -90,13 +94,12 @@ export default class AppSelectPeers {
this.container.classList.add('selector');
let needSwitchList = false;
const f = (this.renderResultsFunc || this.renderResults).bind(this);
this.renderResultsFunc = (peerIds: number[]) => {
if(needSwitchList) {
if(this.needSwitchList) {
this.scrollable.splitUp.replaceWith(this.list);
this.scrollable.setVirtualContainer(this.list);
needSwitchList = false;
this.needSwitchList = false;
}
peerIds = peerIds.filter(peerId => {
@ -181,35 +184,8 @@ export default class AppSelectPeers { @@ -181,35 +184,8 @@ export default class AppSelectPeers {
checkbox.checked = !checkbox.checked;
});
this.input.addEventListener('input', () => {
const value = this.input.value;
if(this.query !== value) {
if(this.peerType.includes('contacts')) {
this.cachedContacts = null;
}
if(this.peerType.includes('dialogs')) {
this.folderId = 0;
this.offsetIndex = 0;
}
for(let i in this.tempIds) {
// @ts-ignore
++this.tempIds[i];
}
this.list = appDialogsManager.createChatList();
this.promise = null;
this.loadedWhat = {};
this.query = value;
this.renderedPeerIds.clear();
needSwitchList = true;
//console.log('selectPeers input:', this.query);
this.getMoreResults();
}
});
const debouncedInput = debounce(this.onInput, 200, false, true);
this.input.addEventListener('input', debouncedInput);
this.scrollable.onScrolledBottom = () => {
this.getMoreResults();
@ -229,6 +205,36 @@ export default class AppSelectPeers { @@ -229,6 +205,36 @@ export default class AppSelectPeers {
}, 0);
}
private onInput = () => {
const value = this.input.value;
if(this.query !== value) {
if(this.peerType.includes('contacts')) {
this.cachedContacts = null;
}
if(this.peerType.includes('dialogs')) {
this.folderId = 0;
this.offsetIndex = 0;
}
for(let i in this.tempIds) {
// @ts-ignore
++this.tempIds[i];
}
this.list = appDialogsManager.createChatList();
this.promise = null;
this.loadedWhat = {};
this.query = value;
this.renderedPeerIds.clear();
this.needSwitchList = true;
//console.log('selectPeers input:', this.query);
this.getMoreResults();
}
};
private renderSaved() {
if(!this.offsetIndex && this.folderId === 0 && this.peerType.includes('dialogs') && (!this.query || appUsersManager.testSelfSearch(this.query))) {
this.renderResultsFunc([rootScope.myId]);
@ -254,14 +260,15 @@ export default class AppSelectPeers { @@ -254,14 +260,15 @@ export default class AppSelectPeers {
const pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
const tempId = this.getTempId('dialogs');
this.promise = appMessagesManager.getConversations(this.query, this.offsetIndex, pageCount, this.folderId);
const value = await this.promise;
this.promise = null;
const promise = appMessagesManager.getConversations(this.query, this.offsetIndex, pageCount, this.folderId);
this.promise = promise;
const value = await promise;
if(this.tempIds.dialogs !== tempId) {
return;
}
this.promise = null;
let dialogs = value.dialogs as Dialog[];
if(dialogs.length) {
const newOffsetIndex = dialogs[dialogs.length - 1].index || 0;
@ -270,9 +277,7 @@ export default class AppSelectPeers { @@ -270,9 +277,7 @@ export default class AppSelectPeers {
dialogs.findAndSplice(d => d.peerId === rootScope.myId); // no my account
if(this.chatRightsAction) {
dialogs = dialogs.filter(d => {
return (d.peerId > 0 && (this.chatRightsAction !== 'send_messages' || appUsersManager.canSendToUser(d.peerId))) || appChatsManager.hasRights(-d.peerId, this.chatRightsAction);
});
dialogs = dialogs.filter(d => this.filterByRights(d.peerId));
}
this.renderSaved();
@ -280,7 +285,9 @@ export default class AppSelectPeers { @@ -280,7 +285,9 @@ export default class AppSelectPeers {
this.offsetIndex = newOffsetIndex;
this.renderResultsFunc(dialogs.map(dialog => dialog.peerId));
} else {
}
if(value.isEnd) {
if(!this.loadedWhat.dialogs) {
this.renderSaved();
@ -299,6 +306,13 @@ export default class AppSelectPeers { @@ -299,6 +306,13 @@ export default class AppSelectPeers {
}
}
private filterByRights(peerId: number) {
return (
peerId > 0 &&
(this.chatRightsAction !== 'send_messages' || appUsersManager.canSendToUser(peerId))
) || appChatsManager.hasRights(-peerId, this.chatRightsAction);
}
private async getMoreContacts() {
if(this.promise) return this.promise;
@ -315,12 +329,31 @@ export default class AppSelectPeers { @@ -315,12 +329,31 @@ export default class AppSelectPeers {
this.promise = Promise.all(promises);
this.cachedContacts = (await this.promise)[0].slice(); */
const tempId = this.getTempId('contacts');
this.promise = appUsersManager.getContacts(this.query);
this.cachedContacts = (await this.promise).slice();
const promise = Promise.all([
appUsersManager.getContacts(this.query),
this.query ? appUsersManager.searchContacts(this.query) : undefined
]);
this.promise = promise;
const [cachedContacts, searchResult] = await promise;
if(this.tempIds.contacts !== tempId) {
return;
}
if(searchResult) {
let resultPeerIds = searchResult.my_results.concat(searchResult.results);
if(this.chatRightsAction) {
resultPeerIds = resultPeerIds.filter(peerId => this.filterByRights(peerId));
}
if(!this.peerType.includes('dialogs')) {
resultPeerIds = resultPeerIds.filter(peerId => peerId > 0);
}
this.cachedContacts = filterUnique(cachedContacts.concat(resultPeerIds));
} else this.cachedContacts = cachedContacts.slice();
this.cachedContacts.findAndSplice(userId => userId === rootScope.myId); // no my account
this.promise = null;
}
@ -470,6 +503,11 @@ export default class AppSelectPeers { @@ -470,6 +503,11 @@ export default class AppSelectPeers {
return;
}
if(this.query.trim()) {
this.input.value = '';
this.onInput();
}
const div = document.createElement('div');
div.classList.add('selector-user', 'scale-in');

4
src/lib/appManagers/appUsersManager.ts

@ -797,10 +797,10 @@ export class AppUsersManager { @@ -797,10 +797,10 @@ export class AppUsersManager {
});
} */
public searchContacts(query: string, limit = 20) {
return apiManager.invokeApiSingle('contacts.search', {
return apiManager.invokeApiCacheable('contacts.search', {
q: query,
limit
}).then(peers => {
}, {cacheSeconds: 60}).then(peers => {
this.saveApiUsers(peers.users);
appChatsManager.saveApiChats(peers.chats);

1
src/scss/partials/popups/_forward.scss

@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
display: flex;
width: 100%;
flex-direction: row;
flex: 1 1 auto;
}
.selector {

Loading…
Cancel
Save