Fix autocomplete regex
Increase download chunks limit
This commit is contained in:
parent
699da948e5
commit
0f7522e32a
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 => {
|
||||||
|
@ -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);
|
||||||
if(!matches) {
|
|
||||||
this.previousQuery = undefined;
|
|
||||||
this.autocompleteHelperController.hideOtherHelpers();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.previousQuery === matches[0]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.previousQuery = matches[0];
|
|
||||||
|
|
||||||
let foundHelper: AutocompleteHelper;
|
let foundHelper: AutocompleteHelper;
|
||||||
|
if(!matches) {
|
||||||
|
foundHelper = this.checkInlineAutocomplete(value);
|
||||||
|
// this.previousQuery = undefined;
|
||||||
|
this.autocompleteHelperController.hideOtherHelpers(foundHelper);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if(this.previousQuery === matches[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.previousQuery = matches[0]; */
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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 || [];
|
||||||
|
@ -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 default function cleanSearchText(text: string, latinize = true) {
|
export function clearBadCharsAndTrim(text: string) {
|
||||||
const hasTag = text.charAt(0) === '%';
|
return text.replace(badCharsRe, '').replace(trimRe, '');
|
||||||
text = text.replace(badCharsRe, '').replace(trimRe, '');
|
}
|
||||||
if(latinize) {
|
|
||||||
text = text.replace(/[^A-Za-z0-9]/g, (ch) => {
|
export function latinizeString(text: string) {
|
||||||
|
return text.replace(/[^A-Za-z0-9]/g, (ch) => {
|
||||||
const latinizeCh = Config.LatinizeMap[ch];
|
const latinizeCh = Config.LatinizeMap[ch];
|
||||||
return latinizeCh !== undefined ? latinizeCh : ch;
|
return latinizeCh !== undefined ? latinizeCh : ch;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function cleanSearchText(text: string, latinize = true) {
|
||||||
|
const hasTag = text.charAt(0) === '%';
|
||||||
|
text = clearBadCharsAndTrim(text);
|
||||||
|
if(latinize) text = latinizeString(text);
|
||||||
|
|
||||||
text = text.toLowerCase();
|
text = text.toLowerCase();
|
||||||
if(hasTag) {
|
if(hasTag) text = '%' + text;
|
||||||
text = '%' + text;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 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;
|
||||||
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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 if(chatId) {
|
||||||
|
promise = (this.getChatFull(chatId) as Promise<ChatFull.chatFull>).then(chatFull => {
|
||||||
|
return (chatFull.participants as ChatParticipants.chatParticipants).participants.map(p => p.user_id);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return (this.getChatFull(chatId) as Promise<ChatFull.chatFull>).then(chatFull => {
|
promise = Promise.resolve([]);
|
||||||
return processUserIds((chatFull.participants as ChatParticipants.chatParticipants).participants.map(p => p.user_id));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
@ -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: {
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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) {
|
||||||
|
@ -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}> = [];
|
||||||
|
@ -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,
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user