Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.7 KiB
110 lines
2.7 KiB
4 years ago
|
import Config from './config';
|
||
|
|
||
|
class SearchIndexManager {
|
||
|
public static badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<]+/g;
|
||
|
public static trimRe = /^\s+|\s$/g;
|
||
|
|
||
|
public createIndex() {
|
||
|
return {
|
||
|
shortIndexes: {},
|
||
|
fullTexts: {}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public cleanSearchText(text: string, latinize = true) {
|
||
|
const hasTag = text.charAt(0) == '%';
|
||
|
text = text.replace(SearchIndexManager['badCharsRe'], '').replace(SearchIndexManager['trimRe'], '');
|
||
|
if(latinize) {
|
||
|
text = text.replace(/[^A-Za-z0-9]/g, (ch) => {
|
||
|
const latinizeCh = Config.LatinizeMap[ch];
|
||
|
return latinizeCh !== undefined ? latinizeCh : ch;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
text = text.toLowerCase();
|
||
|
if(hasTag) {
|
||
|
text = '%' + text;
|
||
|
}
|
||
|
|
||
|
return text;
|
||
|
}
|
||
|
|
||
|
public cleanUsername(username: string) {
|
||
|
return username && username.toLowerCase() || '';
|
||
|
}
|
||
|
|
||
|
public indexObject(id: number, searchText: string, searchIndex: any) {
|
||
|
if(searchIndex.fullTexts[id] !== undefined) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
searchText = this.cleanSearchText(searchText);
|
||
|
|
||
|
if(!searchText.length) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
const shortIndexes = searchIndex.shortIndexes;
|
||
|
|
||
|
searchIndex.fullTexts[id] = searchText;
|
||
|
|
||
|
searchText.split(' ').forEach((searchWord) => {
|
||
|
let len = Math.min(searchWord.length, 3),
|
||
|
wordPart, i;
|
||
|
for(i = 1; i <= len; i++) {
|
||
|
wordPart = searchWord.substr(0, i);
|
||
|
if(shortIndexes[wordPart] === undefined) {
|
||
|
shortIndexes[wordPart] = [id];
|
||
|
} else {
|
||
|
shortIndexes[wordPart].push(id);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public search(query: string, searchIndex: any) {
|
||
|
const shortIndexes = searchIndex.shortIndexes;
|
||
|
const fullTexts = searchIndex.fullTexts;
|
||
|
|
||
|
query = this.cleanSearchText(query);
|
||
|
|
||
|
const queryWords = query.split(' ');
|
||
|
let foundObjs: any = false,
|
||
|
newFoundObjs: any, i: number;
|
||
|
let j: number, searchText: string;
|
||
|
let found: boolean;
|
||
|
|
||
|
for(i = 0; i < queryWords.length; i++) {
|
||
|
newFoundObjs = shortIndexes[queryWords[i].substr(0, 3)];
|
||
|
if(!newFoundObjs) {
|
||
|
foundObjs = [];
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(foundObjs === false || foundObjs.length > newFoundObjs.length) {
|
||
|
foundObjs = newFoundObjs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
newFoundObjs = {};
|
||
|
|
||
|
for(j = 0; j < foundObjs.length; j++) {
|
||
|
found = true;
|
||
|
searchText = fullTexts[foundObjs[j]];
|
||
|
for(i = 0; i < queryWords.length; i++) {
|
||
|
if(searchText.indexOf(queryWords[i]) == -1) {
|
||
|
found = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(found) {
|
||
|
newFoundObjs[foundObjs[j]] = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return newFoundObjs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default new SearchIndexManager();
|