Handle t.me/addstickers
This commit is contained in:
parent
6bc80a5ac0
commit
ad4e70759d
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import PopupElement from ".";
|
import PopupElement from ".";
|
||||||
import appStickersManager from "../../lib/appManagers/appStickersManager";
|
import appStickersManager, { AppStickersManager } from "../../lib/appManagers/appStickersManager";
|
||||||
import { RichTextProcessor } from "../../lib/richtextprocessor";
|
import { RichTextProcessor } from "../../lib/richtextprocessor";
|
||||||
import Scrollable from "../scrollable";
|
import Scrollable from "../scrollable";
|
||||||
import { wrapSticker } from "../wrappers";
|
import { wrapSticker } from "../wrappers";
|
||||||
@ -29,11 +29,7 @@ export default class PopupStickers extends PopupElement {
|
|||||||
|
|
||||||
private set: StickerSet.stickerSet;
|
private set: StickerSet.stickerSet;
|
||||||
|
|
||||||
constructor(private stickerSetInput: {
|
constructor(private stickerSetInput: Parameters<AppStickersManager['getStickerSet']>[0]) {
|
||||||
//_: 'inputStickerSetID',
|
|
||||||
id: string,
|
|
||||||
access_hash: string
|
|
||||||
}) {
|
|
||||||
super('popup-stickers', null, {closable: true, overlayClosable: true, body: true});
|
super('popup-stickers', null, {closable: true, overlayClosable: true, body: true});
|
||||||
|
|
||||||
this.h6 = document.createElement('h6');
|
this.h6 = document.createElement('h6');
|
||||||
|
@ -248,7 +248,7 @@ export class ApiUpdatesManager {
|
|||||||
|
|
||||||
const promise = apiManager.invokeApi('updates.getDifference', {
|
const promise = apiManager.invokeApi('updates.getDifference', {
|
||||||
pts: updatesState.pts,
|
pts: updatesState.pts,
|
||||||
pts_total_limit: first/* && false */ ? 50/* 1200 */ : undefined,
|
pts_total_limit: first && false ? 50/* 1200 */ : undefined,
|
||||||
date: updatesState.date,
|
date: updatesState.date,
|
||||||
qts: -1
|
qts: -1
|
||||||
}, {
|
}, {
|
||||||
|
@ -59,6 +59,7 @@ import whichChild from '../../helpers/dom/whichChild';
|
|||||||
import appEmojiManager from './appEmojiManager';
|
import appEmojiManager from './appEmojiManager';
|
||||||
import PopupElement from '../../components/popups';
|
import PopupElement from '../../components/popups';
|
||||||
import singleInstance from '../mtproto/singleInstance';
|
import singleInstance from '../mtproto/singleInstance';
|
||||||
|
import PopupStickers from '../../components/popups/stickers';
|
||||||
|
|
||||||
//console.log('appImManager included33!');
|
//console.log('appImManager included33!');
|
||||||
|
|
||||||
@ -223,9 +224,7 @@ export class AppImManager {
|
|||||||
stateStorage.setToCache('chatPositions', c || {});
|
stateStorage.setToCache('chatPositions', c || {});
|
||||||
});
|
});
|
||||||
|
|
||||||
(window as any).showMaskedAlert = (element: HTMLAnchorElement, e: Event) => {
|
this.addAnchorListener('showMaskedAlert', (params, element) => {
|
||||||
cancelEvent(null);
|
|
||||||
|
|
||||||
const href = element.href;
|
const href = element.href;
|
||||||
|
|
||||||
const a = element.cloneNode(true) as HTMLAnchorElement;
|
const a = element.cloneNode(true) as HTMLAnchorElement;
|
||||||
@ -244,19 +243,9 @@ export class AppImManager {
|
|||||||
},
|
},
|
||||||
}]
|
}]
|
||||||
}).show();
|
}).show();
|
||||||
|
}, false);
|
||||||
|
|
||||||
return false;
|
this.addAnchorListener('execBotCommand', (params) => {
|
||||||
};
|
|
||||||
|
|
||||||
(window as any).execBotCommand = (element: HTMLAnchorElement, e: Event) => {
|
|
||||||
cancelEvent(null);
|
|
||||||
|
|
||||||
const href = element.href;
|
|
||||||
const params = this.parseUriParams(href);
|
|
||||||
if(!params) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {command, bot} = params;
|
const {command, bot} = params;
|
||||||
|
|
||||||
/* const promise = bot ? this.openUsername(bot).then(() => this.chat.peerId) : Promise.resolve(this.chat.peerId);
|
/* const promise = bot ? this.openUsername(bot).then(() => this.chat.peerId) : Promise.resolve(this.chat.peerId);
|
||||||
@ -267,23 +256,35 @@ export class AppImManager {
|
|||||||
appMessagesManager.sendText(this.chat.peerId, '/' + command + (bot ? '@' + bot : ''));
|
appMessagesManager.sendText(this.chat.peerId, '/' + command + (bot ? '@' + bot : ''));
|
||||||
|
|
||||||
//console.log(command, bot);
|
//console.log(command, bot);
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
this.addAnchorListener('searchByHashtag', (params) => {
|
||||||
};
|
|
||||||
|
|
||||||
(window as any).searchByHashtag = (element: HTMLAnchorElement, e: Event) => {
|
|
||||||
cancelEvent(null);
|
|
||||||
|
|
||||||
const href = element.href;
|
|
||||||
const params = this.parseUriParams(href);
|
|
||||||
if(!params) {
|
if(!params) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {hashtag} = params;
|
const {hashtag} = params;
|
||||||
this.chat.initSearch('#' + hashtag + ' ');
|
this.chat.initSearch('#' + hashtag + ' ');
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
this.addAnchorListener('addstickers', (params) => {
|
||||||
|
new PopupStickers({id: params[1]}).show();
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private addAnchorListener(name: 'showMaskedAlert' | 'execBotCommand' | 'searchByHashtag' | 'addstickers',
|
||||||
|
callback: (params: any, element: HTMLAnchorElement) => boolean | void, parseParams = true) {
|
||||||
|
(window as any)[name] = (element: HTMLAnchorElement, e: Event) => {
|
||||||
|
cancelEvent(null);
|
||||||
|
|
||||||
|
const href = element.href;
|
||||||
|
let params: any;
|
||||||
|
if(parseParams) {
|
||||||
|
params = !element.href.includes('#') ? new URL(element.href).pathname.split('/').slice(1) : this.parseUriParams(href);
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = callback(params, element);
|
||||||
|
return res === undefined ? res : false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,11 @@ import DATABASE_STATE from '../../config/databases/state';
|
|||||||
|
|
||||||
const CACHE_TIME = 3600e3;
|
const CACHE_TIME = 3600e3;
|
||||||
|
|
||||||
|
export type MyStickerSetInput = {
|
||||||
|
id: string,
|
||||||
|
access_hash?: string
|
||||||
|
};
|
||||||
|
|
||||||
export class AppStickersManager {
|
export class AppStickersManager {
|
||||||
private storage = new AppStorage<Record<string, MessagesStickerSet>, typeof DATABASE_STATE>(DATABASE_STATE, 'stickerSets');
|
private storage = new AppStorage<Record<string, MessagesStickerSet>, typeof DATABASE_STATE>(DATABASE_STATE, 'stickerSets');
|
||||||
|
|
||||||
@ -23,7 +28,7 @@ export class AppStickersManager {
|
|||||||
private getStickersByEmoticonsPromises: {[emoticon: string]: Promise<Document[]>} = {};
|
private getStickersByEmoticonsPromises: {[emoticon: string]: Promise<Document[]>} = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.getStickerSet({id: 'emoji', access_hash: ''});
|
this.getStickerSet({id: 'emoji'}, {saveById: true});
|
||||||
|
|
||||||
rootScope.addMultipleEventsListeners({
|
rootScope.addMultipleEventsListeners({
|
||||||
updateNewStickerSet: (update) => {
|
updateNewStickerSet: (update) => {
|
||||||
@ -42,24 +47,23 @@ export class AppStickersManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getStickerSet(set: {
|
public async getStickerSet(set: MyStickerSetInput, params: Partial<{
|
||||||
id: string,
|
|
||||||
access_hash: string
|
|
||||||
}, params: Partial<{
|
|
||||||
overwrite: boolean,
|
overwrite: boolean,
|
||||||
useCache: boolean
|
useCache: boolean,
|
||||||
|
saveById: boolean
|
||||||
}> = {}): Promise<MessagesStickerSet> {
|
}> = {}): Promise<MessagesStickerSet> {
|
||||||
if(this.getStickerSetPromises[set.id]) {
|
const id = set.id;
|
||||||
return this.getStickerSetPromises[set.id];
|
if(this.getStickerSetPromises[id]) {
|
||||||
|
return this.getStickerSetPromises[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getStickerSetPromises[set.id] = new Promise(async(resolve) => {
|
return this.getStickerSetPromises[id] = new Promise(async(resolve) => {
|
||||||
if(!params.overwrite) {
|
if(!params.overwrite) {
|
||||||
const cachedSet = await this.storage.get(set.id);
|
const cachedSet = await this.storage.get(id);
|
||||||
if(cachedSet && cachedSet.documents?.length && ((Date.now() - cachedSet.refreshTime) < CACHE_TIME || params.useCache)) {
|
if(cachedSet && cachedSet.documents?.length && ((Date.now() - cachedSet.refreshTime) < CACHE_TIME || params.useCache)) {
|
||||||
this.saveStickers(cachedSet.documents);
|
this.saveStickers(cachedSet.documents);
|
||||||
resolve(cachedSet);
|
resolve(cachedSet);
|
||||||
delete this.getStickerSetPromises[set.id];
|
delete this.getStickerSetPromises[id];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,14 +73,15 @@ export class AppStickersManager {
|
|||||||
stickerset: this.getStickerSetInput(set)
|
stickerset: this.getStickerSetInput(set)
|
||||||
});
|
});
|
||||||
|
|
||||||
this.saveStickerSet(stickerSet, set.id);
|
const saveById = params.saveById ? id : stickerSet.set.id;
|
||||||
|
this.saveStickerSet(stickerSet, saveById);
|
||||||
|
|
||||||
resolve(stickerSet);
|
resolve(stickerSet);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
resolve(null);
|
resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.getStickerSetPromises[set.id];
|
delete this.getStickerSetPromises[id];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,14 +163,23 @@ export class AppStickersManager {
|
|||||||
//return promise;
|
//return promise;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
public getStickerSetInput(set: {id: string, access_hash: string}): InputStickerSet {
|
public getStickerSetInput(set: MyStickerSetInput): InputStickerSet {
|
||||||
return set.id === 'emoji' ? {
|
if(set.id === 'emoji') {
|
||||||
_: 'inputStickerSetAnimatedEmoji'
|
return {
|
||||||
} : {
|
_: 'inputStickerSetAnimatedEmoji'
|
||||||
_: 'inputStickerSetID',
|
};
|
||||||
id: set.id,
|
} else if(!set.access_hash) {
|
||||||
access_hash: set.access_hash
|
return {
|
||||||
};
|
_: 'inputStickerSetShortName',
|
||||||
|
short_name: set.id
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
_: 'inputStickerSetID',
|
||||||
|
id: set.id,
|
||||||
|
access_hash: set.access_hash
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getFeaturedStickers() {
|
public async getFeaturedStickers() {
|
||||||
|
@ -354,6 +354,10 @@ export default class IDBStorage<T extends Database<any>> {
|
|||||||
|
|
||||||
return this.openDatabase().then((db) => {
|
return this.openDatabase().then((db) => {
|
||||||
return new Promise<T>((resolve, reject) => {
|
return new Promise<T>((resolve, reject) => {
|
||||||
|
/* if(mode === 'readwrite') {
|
||||||
|
return;
|
||||||
|
} */
|
||||||
|
|
||||||
const transaction = db.transaction([storeName], mode);
|
const transaction = db.transaction([storeName], mode);
|
||||||
|
|
||||||
transaction.onerror = (e) => {
|
transaction.onerror = (e) => {
|
||||||
|
@ -573,12 +573,15 @@ namespace RichTextProcessor {
|
|||||||
const entityText = text.substr(entity.offset, entity.length);
|
const entityText = text.substr(entity.offset, entity.length);
|
||||||
|
|
||||||
// let inner: string;
|
// let inner: string;
|
||||||
let url: string;
|
let url: string = (entity as MessageEntity.messageEntityTextUrl).url || entityText;
|
||||||
let masked = false;
|
let masked = false;
|
||||||
if(entity._ === 'messageEntityTextUrl') {
|
let onclick: string;
|
||||||
url = (entity as MessageEntity.messageEntityTextUrl).url;
|
|
||||||
url = wrapUrl(url, true);
|
|
||||||
|
|
||||||
|
const wrapped = wrapUrl(url, true);
|
||||||
|
url = wrapped.url;
|
||||||
|
onclick = wrapped.onclick;
|
||||||
|
|
||||||
|
if(entity._ === 'messageEntityTextUrl') {
|
||||||
const nextEntity = entities[i + 1];
|
const nextEntity = entities[i + 1];
|
||||||
if(nextEntity?._ === 'messageEntityUrl' &&
|
if(nextEntity?._ === 'messageEntityUrl' &&
|
||||||
nextEntity.length === entity.length &&
|
nextEntity.length === entity.length &&
|
||||||
@ -590,11 +593,13 @@ namespace RichTextProcessor {
|
|||||||
masked = true;
|
masked = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
url = wrapUrl(entityText, false);
|
|
||||||
//inner = encodeEntities(replaceUrlEncodings(entityText));
|
//inner = encodeEntities(replaceUrlEncodings(entityText));
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentContext = url[0] === '#';
|
const currentContext = url[0] === '#';
|
||||||
|
if(!onclick && masked && !currentContext) {
|
||||||
|
onclick = 'showMaskedAlert';
|
||||||
|
}
|
||||||
|
|
||||||
const href = (currentContext || typeof electronHelpers === 'undefined')
|
const href = (currentContext || typeof electronHelpers === 'undefined')
|
||||||
? encodeEntities(url)
|
? encodeEntities(url)
|
||||||
@ -603,7 +608,7 @@ namespace RichTextProcessor {
|
|||||||
const target = (currentContext || typeof electronHelpers !== 'undefined')
|
const target = (currentContext || typeof electronHelpers !== 'undefined')
|
||||||
? '' : ' target="_blank" rel="noopener noreferrer"';
|
? '' : ' target="_blank" rel="noopener noreferrer"';
|
||||||
|
|
||||||
insertPart(entity, `<a class="anchor-url" href="${href}"${target}${masked && !currentContext ? 'onclick="showMaskedAlert(this)"' : ''}>`, '</a>');
|
insertPart(entity, `<a class="anchor-url" href="${href}"${target}${onclick ? `onclick="${onclick}(this)"` : ''}>`, '</a>');
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -789,13 +794,14 @@ namespace RichTextProcessor {
|
|||||||
return wrapRichText(text, {entities});
|
return wrapRichText(text, {entities});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapUrl(url: string, unsafe?: number | boolean): string {
|
export function wrapUrl(url: string, unsafe?: number | boolean): {url: string, onclick: string} {
|
||||||
if(!matchUrlProtocol(url)) {
|
if(!matchUrlProtocol(url)) {
|
||||||
url = 'https://' + url;
|
url = 'https://' + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tgMeMatch;
|
let tgMeMatch;
|
||||||
let telescoPeMatch;
|
let telescoPeMatch;
|
||||||
|
let onclick: string;
|
||||||
/* if(unsafe === 2) {
|
/* if(unsafe === 2) {
|
||||||
url = 'tg://unsafe_url?url=' + encodeURIComponent(url);
|
url = 'tg://unsafe_url?url=' + encodeURIComponent(url);
|
||||||
} else */if((tgMeMatch = url.match(/^(?:https?:\/\/)?t(?:elegram)?\.me\/(.+)/))) {
|
} else */if((tgMeMatch = url.match(/^(?:https?:\/\/)?t(?:elegram)?\.me\/(.+)/))) {
|
||||||
@ -803,12 +809,19 @@ namespace RichTextProcessor {
|
|||||||
const path = fullPath.split('/');
|
const path = fullPath.split('/');
|
||||||
switch(path[0]) {
|
switch(path[0]) {
|
||||||
case 'joinchat':
|
case 'joinchat':
|
||||||
|
case 'addstickers':
|
||||||
|
onclick = path[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* case 'joinchat':
|
||||||
|
onclick = 'joinchat';
|
||||||
url = 'tg://join?invite=' + path[1];
|
url = 'tg://join?invite=' + path[1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'addstickers':
|
case 'addstickers':
|
||||||
|
onclick = 'addstickers';
|
||||||
url = 'tg://addstickers?set=' + path[1];
|
url = 'tg://addstickers?set=' + path[1];
|
||||||
break;
|
break; */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if(path[1] && path[1].match(/^\d+$/)) { // https://t.me/.+/[0-9]+ (channel w/ username)
|
if(path[1] && path[1].match(/^\d+$/)) { // https://t.me/.+/[0-9]+ (channel w/ username)
|
||||||
@ -846,7 +859,7 @@ namespace RichTextProcessor {
|
|||||||
url = 'tg://unsafe_url?url=' + encodeURIComponent(url);
|
url = 'tg://unsafe_url?url=' + encodeURIComponent(url);
|
||||||
} */
|
} */
|
||||||
|
|
||||||
return url;
|
return {url, onclick};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function matchUrlProtocol(text: string) {
|
export function matchUrlProtocol(text: string) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user