Browse Source

Fix autocomplete regex

Increase download chunks limit
master
Eduard Kuzmenko 3 years ago
parent
commit
0f7522e32a
  1. 2
      src/components/appSearchSuper..ts
  2. 2
      src/components/chat/chat.ts
  3. 4
      src/components/chat/commandsHelper.ts
  4. 57
      src/components/chat/input.ts
  5. 4
      src/components/chat/mentionsHelper.ts
  6. 2
      src/components/sidebarLeft/index.ts
  7. 40
      src/helpers/cleanSearchText.ts
  8. 2
      src/lib/appManagers/appDialogsManager.ts
  9. 2
      src/lib/appManagers/appEmojiManager.ts
  10. 28
      src/lib/appManagers/appProfileManager.ts
  11. 11
      src/lib/appManagers/appStateManager.ts
  12. 42
      src/lib/appManagers/appUsersManager.ts
  13. 2
      src/lib/mtproto/apiFileManager.ts
  14. 13
      src/lib/searchIndex.ts
  15. 7
      src/lib/storages/dialogs.ts
  16. 6
      src/scss/partials/_chat.scss

2
src/components/appSearchSuper..ts

@ -823,7 +823,7 @@ export default class AppSearchSuper {
}; };
return Promise.all([ return Promise.all([
appUsersManager.getTopPeers().then(peers => { appUsersManager.getTopPeers('correspondents').then(peers => {
if(!middleware()) return; if(!middleware()) return;
const idx = peers.indexOf(rootScope.myId); const idx = peers.indexOf(rootScope.myId);

2
src/components/chat/chat.ts

@ -173,7 +173,7 @@ export default class Chat extends EventListenerBase<{
this.topbar = new ChatTopbar(this, appSidebarRight, this.appMessagesManager, this.appPeersManager, this.appChatsManager, this.appNotificationsManager); this.topbar = new ChatTopbar(this, appSidebarRight, this.appMessagesManager, this.appPeersManager, this.appChatsManager, this.appNotificationsManager);
this.bubbles = new ChatBubbles(this, this.appMessagesManager, this.appStickersManager, this.appUsersManager, this.appInlineBotsManager, this.appPhotosManager, this.appPeersManager, this.appProfileManager); this.bubbles = new ChatBubbles(this, this.appMessagesManager, this.appStickersManager, this.appUsersManager, this.appInlineBotsManager, this.appPhotosManager, this.appPeersManager, this.appProfileManager);
this.input = new ChatInput(this, this.appMessagesManager, this.appDocsManager, this.appChatsManager, this.appPeersManager, this.appWebPagesManager, this.appImManager, this.appDraftsManager, this.serverTimeManager, this.appNotificationsManager, this.appEmojiManager); this.input = new ChatInput(this, this.appMessagesManager, this.appDocsManager, this.appChatsManager, this.appPeersManager, this.appWebPagesManager, this.appImManager, this.appDraftsManager, this.serverTimeManager, this.appNotificationsManager, this.appEmojiManager, this.appUsersManager);
this.selection = new ChatSelection(this, this.bubbles, this.input, this.appMessagesManager); this.selection = new ChatSelection(this, this.bubbles, this.input, this.appMessagesManager);
this.contextMenu = new ChatContextMenu(this.bubbles.bubblesContainer, this, this.appMessagesManager, this.appPeersManager, this.appPollsManager, this.appDocsManager); this.contextMenu = new ChatContextMenu(this.bubbles.bubblesContainer, this, this.appMessagesManager, this.appPeersManager, this.appPollsManager, this.appDocsManager);

4
src/components/chat/commandsHelper.ts

@ -41,7 +41,9 @@ export default class CommandsHelper extends AutocompletePeerHelper {
} }
const botInfos: BotInfo.botInfo[] = [].concat(full.bot_info); const botInfos: BotInfo.botInfo[] = [].concat(full.bot_info);
const index = new SearchIndex<string>(false, false); const index = new SearchIndex<string>({
ignoreCase: true
});
const commands: Map<string, {peerId: number, name: string, description: string}> = new Map(); const commands: Map<string, {peerId: number, name: string, description: string}> = new Map();
botInfos.forEach(botInfo => { botInfos.forEach(botInfo => {

57
src/components/chat/input.ts

@ -14,6 +14,7 @@ import type { AppImManager } from '../../lib/appManagers/appImManager';
import type { AppDraftsManager, MyDraftMessage } from '../../lib/appManagers/appDraftsManager'; import type { AppDraftsManager, MyDraftMessage } from '../../lib/appManagers/appDraftsManager';
import type { AppEmojiManager } from '../../lib/appManagers/appEmojiManager'; import type { AppEmojiManager } from '../../lib/appManagers/appEmojiManager';
import type { ServerTimeManager } from '../../lib/mtproto/serverTimeManager'; import type { ServerTimeManager } from '../../lib/mtproto/serverTimeManager';
import type { AppUsersManager } from '../../lib/appManagers/appUsersManager';
import type Chat from './chat'; import type Chat from './chat';
import Recorder from '../../../public/recorder.min'; import Recorder from '../../../public/recorder.min';
import { isTouchSupported } from "../../helpers/touchSupport"; import { isTouchSupported } from "../../helpers/touchSupport";
@ -75,7 +76,7 @@ type ChatInputHelperType = 'edit' | 'webpage' | 'forward' | 'reply';
export default class ChatInput { export default class ChatInput {
// private static AUTO_COMPLETE_REG_EXP = /(\s|^)((?::|.)(?!.*[:@]).*|(?:[@\/]\S*))$/; // private static AUTO_COMPLETE_REG_EXP = /(\s|^)((?::|.)(?!.*[:@]).*|(?:[@\/]\S*))$/;
private static AUTO_COMPLETE_REG_EXP = /(\s|^)((?:(?:@|^\/)\S*)|(?::|[^:@\/])(?!.*[:@\/]).*)$/; private static AUTO_COMPLETE_REG_EXP = /(\s|^)((?:(?:@|^\/)\S*)|(?::|^[^:@\/])(?!.*[:@\/]).*)$/;
public messageInput: HTMLElement; public messageInput: HTMLElement;
public messageInputField: InputField; public messageInputField: InputField;
private fileInput: HTMLInputElement; private fileInput: HTMLInputElement;
@ -169,7 +170,8 @@ export default class ChatInput {
private appDraftsManager: AppDraftsManager, private appDraftsManager: AppDraftsManager,
private serverTimeManager: ServerTimeManager, private serverTimeManager: ServerTimeManager,
private appNotificationsManager: AppNotificationsManager, private appNotificationsManager: AppNotificationsManager,
private appEmojiManager: AppEmojiManager private appEmojiManager: AppEmojiManager,
private appUsersManager: AppUsersManager
) { ) {
this.listenerSetter = new ListenerSetter(); this.listenerSetter = new ListenerSetter();
} }
@ -448,7 +450,8 @@ export default class ChatInput {
this.listenerSetter.add(rootScope)('settings_updated', () => { this.listenerSetter.add(rootScope)('settings_updated', () => {
if(this.stickersHelper || this.emojiHelper) { if(this.stickersHelper || this.emojiHelper) {
this.previousQuery = undefined; // this.previousQuery = undefined;
this.previousQuery = '';
this.checkAutocomplete(); this.checkAutocomplete();
/* if(!rootScope.settings.stickers.suggest) { /* if(!rootScope.settings.stickers.suggest) {
this.stickersHelper.checkEmoticon(''); this.stickersHelper.checkEmoticon('');
@ -1242,20 +1245,27 @@ export default class ChatInput {
value = value.substr(0, caretPos); value = value.substr(0, caretPos);
if(this.previousQuery === value) {
return;
}
this.previousQuery = value;
const matches = value.match(ChatInput.AUTO_COMPLETE_REG_EXP); const matches = value.match(ChatInput.AUTO_COMPLETE_REG_EXP);
let foundHelper: AutocompleteHelper;
if(!matches) { if(!matches) {
this.previousQuery = undefined; foundHelper = this.checkInlineAutocomplete(value);
this.autocompleteHelperController.hideOtherHelpers(); // this.previousQuery = undefined;
this.autocompleteHelperController.hideOtherHelpers(foundHelper);
return; return;
} }
if(this.previousQuery === matches[0]) { /* if(this.previousQuery === matches[0]) {
return; return;
} }
this.previousQuery = matches[0]; this.previousQuery = matches[0]; */
let foundHelper: AutocompleteHelper;
const entity = entities[0]; const entity = entities[0];
const query = matches[2]; const query = matches[2];
@ -1267,14 +1277,9 @@ export default class ChatInput {
entity?._ === 'messageEntityEmoji' && entity.length === value.length && !entity.offset) { entity?._ === 'messageEntityEmoji' && entity.length === value.length && !entity.offset) {
foundHelper = this.stickersHelper; foundHelper = this.stickersHelper;
this.stickersHelper.checkEmoticon(value); this.stickersHelper.checkEmoticon(value);
} else } else if(firstChar === '@') { // mentions
//let query = cleanSearchText(query);
//console.log('autocomplete matches', matches);
if(firstChar === '@') { // mentions
const topMsgId = this.chat.threadId ? this.appMessagesManager.getServerMessageId(this.chat.threadId) : undefined; const topMsgId = this.chat.threadId ? this.appMessagesManager.getServerMessageId(this.chat.threadId) : undefined;
if(this.mentionsHelper.checkQuery(query, this.chat.peerId, topMsgId)) { if(this.mentionsHelper.checkQuery(query, this.chat.peerId > 0 ? 0 : this.chat.peerId, topMsgId)) {
foundHelper = this.mentionsHelper; foundHelper = this.mentionsHelper;
} }
} else if(!matches[1] && firstChar === '/') { // commands } else if(!matches[1] && firstChar === '/') { // commands
@ -1286,11 +1291,33 @@ export default class ChatInput {
foundHelper = this.emojiHelper; foundHelper = this.emojiHelper;
this.emojiHelper.checkQuery(query, firstChar); this.emojiHelper.checkQuery(query, firstChar);
} }
} else {
foundHelper = this.checkInlineAutocomplete(value);
} }
this.autocompleteHelperController.hideOtherHelpers(foundHelper); this.autocompleteHelperController.hideOtherHelpers(foundHelper);
} }
private checkInlineAutocomplete(value: string): AutocompleteHelper {
return;
const inlineMatch = value.match(/^@([a-zA-Z\\d_]{3,32})\s/);
if(inlineMatch) {
const username = inlineMatch[1];
console.log('inline match username', username);
this.appUsersManager.resolveUsername(username).then(peer => {
if(peer._ === 'user') {
if(peer.bot_inline_placeholder) {
this.messageInput.dataset.inlinePlaceholder = peer.bot_inline_placeholder;
}
console.log(peer);
}
});
return;
}
}
private onBtnSendClick = (e: Event) => { private onBtnSendClick = (e: Event) => {
cancelEvent(e); cancelEvent(e);

4
src/components/chat/mentionsHelper.ts

@ -43,9 +43,9 @@ export default class MentionsHelper extends AutocompletePeerHelper {
public checkQuery(query: string, peerId: number, topMsgId: number) { public checkQuery(query: string, peerId: number, topMsgId: number) {
const trimmed = query.trim(); // check that there is no whitespace const trimmed = query.trim(); // check that there is no whitespace
if(peerId > 0 || query.length !== trimmed.length) return false; if(query.length !== trimmed.length) return false;
this.appProfileManager.getMentions(-peerId, trimmed, topMsgId).then(peerIds => { this.appProfileManager.getMentions(peerId ? -peerId : 0, trimmed, topMsgId).then(peerIds => {
const username = trimmed.slice(1).toLowerCase(); const username = trimmed.slice(1).toLowerCase();
this.render(peerIds.map(peerId => { this.render(peerIds.map(peerId => {
const user = this.appUsersManager.getUser(peerId); const user = this.appUsersManager.getUser(peerId);

2
src/components/sidebarLeft/index.ts

@ -246,7 +246,7 @@ export class AppSidebarLeft extends SidebarSlider {
this.archivedCount.classList.toggle('hide', !e.count); this.archivedCount.classList.toggle('hide', !e.count);
}); });
appUsersManager.getTopPeers(); appUsersManager.getTopPeers('correspondents');
appStateManager.getState().then(state => { appStateManager.getState().then(state => {
const recentSearch = state.recentSearch || []; const recentSearch = state.recentSearch || [];

40
src/helpers/cleanSearchText.ts

@ -14,20 +14,40 @@ import Config from "../lib/config";
const badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<]+/g; const badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<]+/g;
const trimRe = /^\s+|\s$/g; const trimRe = /^\s+|\s$/g;
export function clearBadCharsAndTrim(text: string) {
return text.replace(badCharsRe, '').replace(trimRe, '');
}
export function latinizeString(text: string) {
return text.replace(/[^A-Za-z0-9]/g, (ch) => {
const latinizeCh = Config.LatinizeMap[ch];
return latinizeCh !== undefined ? latinizeCh : ch;
});
}
export default function cleanSearchText(text: string, latinize = true) { export default function cleanSearchText(text: string, latinize = true) {
const hasTag = text.charAt(0) === '%'; const hasTag = text.charAt(0) === '%';
text = text.replace(badCharsRe, '').replace(trimRe, ''); text = clearBadCharsAndTrim(text);
if(latinize) { if(latinize) text = latinizeString(text);
text = text.replace(/[^A-Za-z0-9]/g, (ch) => {
const latinizeCh = Config.LatinizeMap[ch];
return latinizeCh !== undefined ? latinizeCh : ch;
});
}
text = text.toLowerCase(); text = text.toLowerCase();
if(hasTag) { if(hasTag) text = '%' + text;
text = '%' + text;
} return text;
}
export type ProcessSearchTextOptions = Partial<{
clearBadChars: boolean,
latinize: boolean,
ignoreCase: boolean,
includeTag: boolean
}>;
export function processSearchText(text: string, options: ProcessSearchTextOptions = {}) {
const hasTag = options.includeTag && text.charAt(0) === '%';
if(options.clearBadChars) text = clearBadCharsAndTrim(text);
if(options.latinize) text = latinizeString(text);
if(options.ignoreCase) text = text.toLowerCase();
if(hasTag) text = '%' + text;
return text; return text;
} }

2
src/lib/appManagers/appDialogsManager.ts

@ -834,7 +834,7 @@ export class AppDialogsManager {
appUsersManager.getContacts().then(users => { appUsersManager.getContacts().then(users => {
let key: LangPackKey, args: FormatterArguments; let key: LangPackKey, args: FormatterArguments;
if(users.length) { if(users.length/* && false */) {
key = 'ChatList.Main.EmptyPlaceholder.Subtitle'; key = 'ChatList.Main.EmptyPlaceholder.Subtitle';
args = [i18n('Contacts.Count', [users.length])]; args = [i18n('Contacts.Count', [users.length])];
} else { } else {

2
src/lib/appManagers/appEmojiManager.ts

@ -166,7 +166,7 @@ export class AppEmojiManager {
public indexEmojis() { public indexEmojis() {
if(!this.index) { if(!this.index) {
this.index = new SearchIndex(false, false, 2); this.index = new SearchIndex(undefined, 2);
} }
for(const langCode in this.keywordLangPacks) { for(const langCode in this.keywordLangPacks) {

28
src/lib/appManagers/appProfileManager.ts

@ -397,11 +397,15 @@ export class AppProfileManager {
public getMentions(chatId: number, query: string, threadId?: number): Promise<number[]> { public getMentions(chatId: number, query: string, threadId?: number): Promise<number[]> {
const processUserIds = (userIds: number[]) => { const processUserIds = (userIds: number[]) => {
const startsWithAt = query.charAt(0) === '@';
if(startsWithAt) query = query.slice(1);
/* const startsWithAt = query.charAt(0) === '@'; /* const startsWithAt = query.charAt(0) === '@';
if(startsWithAt) query = query.slice(1); if(startsWithAt) query = query.slice(1);
const index = new SearchIndex<number>(!startsWithAt, !startsWithAt); */ const index = new SearchIndex<number>(!startsWithAt, !startsWithAt); */
const index = new SearchIndex<number>(true, true); const index = new SearchIndex<number>({
ignoreCase: true
});
userIds.forEach(userId => { userIds.forEach(userId => {
index.indexObject(userId, appUsersManager.getUserSearchText(userId)); index.indexObject(userId, appUsersManager.getUserSearchText(userId));
}); });
@ -409,19 +413,31 @@ export class AppProfileManager {
return Array.from(index.search(query)); return Array.from(index.search(query));
}; };
let promise: Promise<number[]>;
if(appChatsManager.isChannel(chatId)) { if(appChatsManager.isChannel(chatId)) {
return this.getChannelParticipants(chatId, { promise = this.getChannelParticipants(chatId, {
_: 'channelParticipantsMentions', _: 'channelParticipantsMentions',
q: query, q: query,
top_msg_id: threadId top_msg_id: threadId
}, 50, 0).then(cP => { }, 50, 0).then(cP => {
return processUserIds(cP.participants.map(p => appChatsManager.getParticipantPeerId(p))); return cP.participants.map(p => appChatsManager.getParticipantPeerId(p));
}); });
} else { } else if(chatId) {
return (this.getChatFull(chatId) as Promise<ChatFull.chatFull>).then(chatFull => { promise = (this.getChatFull(chatId) as Promise<ChatFull.chatFull>).then(chatFull => {
return processUserIds((chatFull.participants as ChatParticipants.chatParticipants).participants.map(p => p.user_id)); return (chatFull.participants as ChatParticipants.chatParticipants).participants.map(p => p.user_id);
}); });
} else {
promise = Promise.resolve([]);
} }
return Promise.all([
[],// appUsersManager.getTopPeers('bots_inline').catch(() => []),
promise
]).then(results => {
const peerIds = results[0].concat(results[1]);
return processUserIds(peerIds);
});
} }
public invalidateChannelParticipants(id: number) { public invalidateChannelParticipants(id: number) {

11
src/lib/appManagers/appStateManager.ts

@ -6,7 +6,7 @@
import type { Dialog } from './appMessagesManager'; import type { Dialog } from './appMessagesManager';
import type { UserAuth } from '../mtproto/mtproto_config'; import type { UserAuth } from '../mtproto/mtproto_config';
import type { User } from './appUsersManager'; import type { TopPeerType, User } from './appUsersManager';
import type { AuthState } from '../../types'; import type { AuthState } from '../../types';
import type FiltersStorage from '../storages/filters'; import type FiltersStorage from '../storages/filters';
import type DialogsStorage from '../storages/dialogs'; import type DialogsStorage from '../storages/dialogs';
@ -54,7 +54,12 @@ export type State = {
maxSeenMsgId: number, maxSeenMsgId: number,
stateCreatedTime: number, stateCreatedTime: number,
recentEmoji: string[], recentEmoji: string[],
topPeers: number[], topPeersCache: {
[type in TopPeerType]?: {
peerIds: number[],
cachedTime: number
}
},
recentSearch: number[], recentSearch: number[],
version: typeof STATE_VERSION, version: typeof STATE_VERSION,
authState: AuthState, authState: AuthState,
@ -103,7 +108,7 @@ export const STATE_INIT: State = {
maxSeenMsgId: 0, maxSeenMsgId: 0,
stateCreatedTime: Date.now(), stateCreatedTime: Date.now(),
recentEmoji: [], recentEmoji: [],
topPeers: [], topPeersCache: {},
recentSearch: [], recentSearch: [],
version: STATE_VERSION, version: STATE_VERSION,
authState: { authState: {

42
src/lib/appManagers/appUsersManager.ts

@ -16,7 +16,7 @@ import cleanSearchText from "../../helpers/cleanSearchText";
import cleanUsername from "../../helpers/cleanUsername"; import cleanUsername from "../../helpers/cleanUsername";
import { tsNow } from "../../helpers/date"; import { tsNow } from "../../helpers/date";
import { safeReplaceObject, isObject } from "../../helpers/object"; import { safeReplaceObject, isObject } from "../../helpers/object";
import { InputUser, User as MTUser, UserProfilePhoto, UserStatus } from "../../layer"; import { Chat, InputUser, User as MTUser, UserProfilePhoto, UserStatus } from "../../layer";
import I18n, { i18n, LangPackKey } from "../langPack"; import I18n, { i18n, LangPackKey } from "../langPack";
//import apiManager from '../mtproto/apiManager'; //import apiManager from '../mtproto/apiManager';
import apiManager from '../mtproto/mtprotoworker'; import apiManager from '../mtproto/mtprotoworker';
@ -33,6 +33,7 @@ import appStateManager from "./appStateManager";
// TODO: updateUserBlocked // TODO: updateUserBlocked
export type User = MTUser.user; export type User = MTUser.user;
export type TopPeerType = 'correspondents' | 'bots_inline';
export class AppUsersManager { export class AppUsersManager {
private storage = appStateManager.storages.users; private storage = appStateManager.storages.users;
@ -44,7 +45,7 @@ export class AppUsersManager {
private contactsList: Set<number>; private contactsList: Set<number>;
private updatedContactsList: boolean; private updatedContactsList: boolean;
private getTopPeersPromise: Promise<number[]>; private getTopPeersPromises: {[type in TopPeerType]?: Promise<number[]>};
constructor() { constructor() {
this.clear(true); this.clear(true);
@ -182,7 +183,8 @@ export class AppUsersManager {
this.usernames = {}; this.usernames = {};
} }
this.contactsIndex = new SearchIndex(); this.getTopPeersPromises = {};
this.contactsIndex = this.createSearchIndex();
this.contactsFillPromise = undefined; this.contactsFillPromise = undefined;
this.contactsList = new Set(); this.contactsList = new Set();
this.updatedContactsList = false; this.updatedContactsList = false;
@ -219,7 +221,7 @@ export class AppUsersManager {
return this.contactsFillPromise || (this.contactsFillPromise = promise); return this.contactsFillPromise || (this.contactsFillPromise = promise);
} }
public resolveUsername(username: string) { public resolveUsername(username: string): Promise<Chat | User> {
if(username[0] === '@') { if(username[0] === '@') {
username = username.slice(1); username = username.slice(1);
} }
@ -314,11 +316,20 @@ export class AppUsersManager {
public testSelfSearch(query: string) { public testSelfSearch(query: string) {
const user = this.getSelf(); const user = this.getSelf();
const index = new SearchIndex(); const index = this.createSearchIndex();
index.indexObject(user.id, this.getUserSearchText(user.id)); index.indexObject(user.id, this.getUserSearchText(user.id));
return index.search(query).has(user.id); return index.search(query).has(user.id);
} }
private createSearchIndex() {
return new SearchIndex<number>({
clearBadChars: true,
ignoreCase: true,
latinize: true,
includeTag: true
});
}
public saveApiUsers(apiUsers: any[], override?: boolean) { public saveApiUsers(apiUsers: any[], override?: boolean) {
apiUsers.forEach((user) => this.saveApiUser(user, override)); apiUsers.forEach((user) => this.saveApiUser(user, override));
} }
@ -721,19 +732,20 @@ export class AppUsersManager {
}); });
} */ } */
public getTopPeers(): Promise<number[]> { public getTopPeers(type: TopPeerType): Promise<number[]> {
if(this.getTopPeersPromise) return this.getTopPeersPromise; if(this.getTopPeersPromises[type]) return this.getTopPeersPromises[type];
return this.getTopPeersPromise = appStateManager.getState().then((state) => { return this.getTopPeersPromises[type] = appStateManager.getState().then((state) => {
if(state?.topPeers?.length) { const cached = state.topPeersCache[type];
return state.topPeers; if(cached?.peerIds?.length) {
return cached.peerIds;
} }
return apiManager.invokeApi('contacts.getTopPeers', { return apiManager.invokeApi('contacts.getTopPeers', {
correspondents: true, [type]: true,
offset: 0, offset: 0,
limit: 15, limit: 15,
hash: 0, hash: 0
}).then((result) => { }).then((result) => {
let peerIds: number[] = []; let peerIds: number[] = [];
if(result._ === 'contacts.topPeers') { if(result._ === 'contacts.topPeers') {
@ -750,7 +762,11 @@ export class AppUsersManager {
} }
} }
appStateManager.pushToState('topPeers', peerIds); state.topPeersCache[type] = {
peerIds,
cachedTime: Date.now()
};
appStateManager.pushToState('topPeersCache', state.topPeersCache);
return peerIds; return peerIds;
}); });

2
src/lib/mtproto/apiFileManager.ts

@ -133,7 +133,7 @@ export class ApiFileManager {
private downloadCheck(dcId: string | number) { private downloadCheck(dcId: string | number) {
const downloadPull = this.downloadPulls[dcId]; const downloadPull = this.downloadPulls[dcId];
const downloadLimit = dcId === 'upload' ? 24 : 24; const downloadLimit = dcId === 'upload' ? 24 : 36;
//const downloadLimit = Infinity; //const downloadLimit = Infinity;
if(this.downloadActives[dcId] >= downloadLimit || !downloadPull || !downloadPull.length) { if(this.downloadActives[dcId] >= downloadLimit || !downloadPull || !downloadPull.length) {

13
src/lib/searchIndex.ts

@ -9,14 +9,13 @@
* https://github.com/zhukov/webogram/blob/master/LICENSE * https://github.com/zhukov/webogram/blob/master/LICENSE
*/ */
import cleanSearchText from '../helpers/cleanSearchText'; import { processSearchText, ProcessSearchTextOptions } from '../helpers/cleanSearchText';
export default class SearchIndex<SearchWhat> { export default class SearchIndex<SearchWhat> {
private fullTexts: Map<SearchWhat, string> = new Map(); private fullTexts: Map<SearchWhat, string> = new Map();
// minChars can be 0 because it requires at least one word (one symbol) to be found // minChars can be 0 because it requires at least one word (one symbol) to be found
constructor(private cleanText = true, private latinize = true, private minChars: number = 0) { constructor(private options?: ProcessSearchTextOptions, private minChars = 0) {
} }
public indexObject(id: SearchWhat, searchText: string) { public indexObject(id: SearchWhat, searchText: string) {
@ -24,8 +23,8 @@ export default class SearchIndex<SearchWhat> {
return false; return false;
} */ } */
if(searchText.trim() && this.cleanText) { if(this.options && searchText.trim()) {
searchText = cleanSearchText(searchText, this.latinize); searchText = processSearchText(searchText, this.options);
} }
if(!searchText) { if(!searchText) {
@ -54,8 +53,8 @@ export default class SearchIndex<SearchWhat> {
const fullTexts = this.fullTexts; const fullTexts = this.fullTexts;
//const shortIndexes = searchIndex.shortIndexes; //const shortIndexes = searchIndex.shortIndexes;
if(this.cleanText) { if(this.options) {
query = cleanSearchText(query, this.latinize); query = processSearchText(query, this.options);
} }
const newFoundObjs: Array<{fullText: string, fullTextLength: number, what: SearchWhat, foundChars: number}> = []; const newFoundObjs: Array<{fullText: string, fullTextLength: number, what: SearchWhat, foundChars: number}> = [];

7
src/lib/storages/dialogs.ts

@ -133,7 +133,12 @@ export default class DialogsStorage {
1: [] 1: []
}; };
this.dialogsNum = 0; this.dialogsNum = 0;
this.dialogsIndex = new SearchIndex<number>(); this.dialogsIndex = new SearchIndex<number>({
clearBadChars: true,
ignoreCase: true,
latinize: true,
includeTag: true
});
this.cachedResults = { this.cachedResults = {
query: '', query: '',
count: 0, count: 0,

6
src/scss/partials/_chat.scss

@ -142,6 +142,12 @@ $chat-helper-size: 39px;
@include respond-to(handhelds) { @include respond-to(handhelds) {
max-height: 10rem; max-height: 10rem;
} }
&[data-inline-placeholder]:after {
content: attr(data-inline-placeholder);
color: #a2acb4;
pointer-events: none;
}
} }
.toggle-emoticons { .toggle-emoticons {

Loading…
Cancel
Save