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.
 
 
 
 
 

235 lines
6.8 KiB

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import App from "../../config/app";
import { MOUNT_CLASS_TO } from "../../config/debug";
import { validateInitObject } from "../../helpers/object";
import I18n from "../langPack";
import { isObject } from "../mtproto/bin_utils";
import apiManager from "../mtproto/mtprotoworker";
import SearchIndex from "../searchIndex";
import stateStorage from "../stateStorage";
import appStateManager from "./appStateManager";
type EmojiLangPack = {
keywords: {
[keyword: string]: string[],
},
version: number,
langCode: string
};
const EMOJI_LANG_PACK: EmojiLangPack = {
keywords: {},
version: 0,
langCode: App.langPackCode
};
const RECENT_MAX_LENGTH = 36;
export class AppEmojiManager {
private static POPULAR_EMOJI = ["πŸ˜‚", "😘", "❀️", "😍", "😊", "😁", "πŸ‘", "☺️", "πŸ˜”", "πŸ˜„", "😭", "πŸ’‹", "πŸ˜’", "😳", "😜", "πŸ™ˆ", "πŸ˜‰", "πŸ˜ƒ", "😒", "😝", "😱", "😑", "😏", "😞", "πŸ˜…", "😚", "πŸ™Š", "😌", "πŸ˜€", "πŸ˜‹", "πŸ˜†", "πŸ‘Œ", "😐", "πŸ˜•"];
private keywordLangPacks: {
[langCode: string]: EmojiLangPack
} = {};
private index: SearchIndex<EmojiLangPack['keywords'][keyof EmojiLangPack['keywords']]>;
private indexedLangPacks: {[langCode: string]: boolean} = {};
private getKeywordsPromises: {[langCode: string]: Promise<EmojiLangPack>} = {};
private recent: string[];
private getRecentEmojisPromise: Promise<AppEmojiManager['recent']>;
/* public getPopularEmoji() {
return stateStorage.get('emojis_popular').then(popEmojis => {
var result = []
if (popEmojis && popEmojis.length) {
for (var i = 0, len = popEmojis.length; i < len; i++) {
result.push({code: popEmojis[i][0], rate: popEmojis[i][1]})
}
callback(result)
return
}
return stateStorage.get('emojis_recent').then(recentEmojis => {
recentEmojis = recentEmojis || popular || []
var shortcut
var code
for (var i = 0, len = recentEmojis.length; i < len; i++) {
shortcut = recentEmojis[i]
if (Array.isArray(shortcut)) {
shortcut = shortcut[0]
}
if (shortcut && typeof shortcut === 'string') {
if (shortcut.charAt(0) == ':') {
shortcut = shortcut.substr(1, shortcut.length - 2)
}
if (code = shortcuts[shortcut]) {
result.push({code: code, rate: 1})
}
}
}
callback(result)
});
});
}
function pushPopularEmoji (code) {
getPopularEmoji(function (popularEmoji) {
var exists = false
var count = popularEmoji.length
var result = []
for (var i = 0; i < count; i++) {
if (popularEmoji[i].code == code) {
exists = true
popularEmoji[i].rate++
}
result.push([popularEmoji[i].code, popularEmoji[i].rate])
}
if (exists) {
result.sort(function (a, b) {
return b[1] - a[1]
})
} else {
if (result.length > 41) {
result = result.slice(0, 41)
}
result.push([code, 1])
}
ConfigStorage.set({emojis_popular: result})
})
} */
public getEmojiKeywords(langCode: string = App.langPackCode) {
const promise = this.getKeywordsPromises[langCode];
if(promise) {
return promise;
}
const storageKey: any = 'emojiKeywords_' + langCode;
return this.getKeywordsPromises[langCode] = stateStorage.get(storageKey).then((pack: EmojiLangPack) => {
if(!isObject(pack)) {
pack = {} as any;
}
validateInitObject(EMOJI_LANG_PACK, pack);
// important
pack.langCode = langCode;
this.keywordLangPacks[langCode] = pack;
return apiManager.invokeApi('messages.getEmojiKeywordsDifference', {
lang_code: pack.langCode,
from_version: pack.version
}).then((keywordsDifference) => {
pack.version = keywordsDifference.version;
const packKeywords = pack.keywords;
const keywords = keywordsDifference.keywords;
for(let i = 0, length = keywords.length; i < length; ++i) {
const {keyword, emoticons} = keywords[i];
packKeywords[keyword] = emoticons;
}
stateStorage.set({
[storageKey]: pack
});
return pack;
}, () => {
return pack;
});
});
}
public getBothEmojiKeywords() {
const promises: Promise<any>[] = [
this.getEmojiKeywords()
];
if(I18n.lastRequestedLangCode !== App.langPackCode) {
promises.push(this.getEmojiKeywords(I18n.lastRequestedLangCode));
}
if(!this.recent) {
promises.push(this.getRecentEmojis());
}
return Promise.all(promises);
}
public indexEmojis() {
if(!this.index) {
this.index = new SearchIndex(false, false);
}
for(const langCode in this.keywordLangPacks) {
if(this.indexedLangPacks[langCode]) {
continue;
}
const pack = this.keywordLangPacks[langCode];
const keywords = pack.keywords;
for(const keyword in keywords) {
const emoticons = keywords[keyword];
this.index.indexObject(emoticons, keyword);
}
this.indexedLangPacks[langCode] = true;
}
}
public searchEmojis(q: string) {
this.indexEmojis();
q = q.toLowerCase().replace(/_/g, ' ');
//const perf = performance.now();
let emojis: Array<string>;
if(q.trim()) {
const set = this.index.search(q);
emojis = Array.from(set).reduce((acc, v) => acc.concat(v), []);
} else {
emojis = this.recent.concat(AppEmojiManager.POPULAR_EMOJI).slice(0, RECENT_MAX_LENGTH);
}
emojis = Array.from(new Set(emojis));
//console.log('searchEmojis', q, 'time', performance.now() - perf);
/* for(let i = 0, length = emojis.length; i < length; ++i) {
if(emojis[i].includes(zeroWidthJoiner) && !emojis[i].includes('\ufe0f')) {
emojis[i] += '\ufe0f';
}
} */
return emojis;
}
public getRecentEmojis() {
if(this.getRecentEmojisPromise) return this.getRecentEmojisPromise;
return this.getRecentEmojisPromise = appStateManager.getState().then(state => {
return this.recent = Array.isArray(state.recentEmoji) ? state.recentEmoji : [];
});
}
public pushRecentEmoji(emoji: string) {
this.getRecentEmojis().then(recent => {
recent.findAndSplice(e => e === emoji);
recent.unshift(emoji);
if(recent.length > RECENT_MAX_LENGTH) {
recent.length = RECENT_MAX_LENGTH;
}
appStateManager.pushToState('recentEmoji', recent);
});
}
}
const appEmojiManager = new AppEmojiManager();
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.appEmojiManager = appEmojiManager);
export default appEmojiManager;