diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index c3978cbf8..043f3fd02 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -546,6 +546,10 @@ export class AppImManager extends EventListenerBase<{ this.addAnchorListener<{pathnameParams: ['addstickers', string]}>({ name: 'addstickers', callback: ({pathnameParams}) => { + if(!pathnameParams[1]) { + return; + } + const link: InternalLink = { _: INTERNAL_LINK_TYPE.STICKER_SET, set: pathnameParams[1] @@ -977,7 +981,8 @@ export class AppImManager extends EventListenerBase<{ private addAnchorListener(options: { name: 'showMaskedAlert' | 'execBotCommand' | 'searchByHashtag' | 'addstickers' | 'im' | - 'resolve' | 'privatepost' | 'addstickers' | 'voicechat' | 'joinchat' | 'join' | 'invoice', + 'resolve' | 'privatepost' | 'addstickers' | 'voicechat' | 'joinchat' | 'join' | 'invoice' | + 'emoji', protocol?: 'tg', callback: (params: Params, element?: HTMLAnchorElement) => boolean | any, noPathnameParams?: boolean, @@ -986,11 +991,18 @@ export class AppImManager extends EventListenerBase<{ (window as any)[(options.protocol ? options.protocol + '_' : '') + options.name] = (element?: HTMLAnchorElement/* , e: Event */) => { cancelEvent(null); - const href = element.href; + let href = element.href; let pathnameParams: any[]; let uriParams: any; - if(!options.noPathnameParams) pathnameParams = new URL(element.href).pathname.split('/').slice(1); + const u = new URL(href); + const match = u.host.match(/(.+?)\.t(?:elegram)?\.me/); + if(match) { + u.pathname = match[1] + (u.pathname === '/' ? '' : u.pathname); + href = u.toString(); + } + + if(!options.noPathnameParams) pathnameParams = new URL(href).pathname.split('/').slice(1); if(!options.noUriParams) uriParams = this.parseUriParams(href); const res = options.callback({pathnameParams, uriParams} as Params, element); diff --git a/src/lib/appManagers/internalLink.ts b/src/lib/appManagers/internalLink.ts index 1bd4b1dd5..0de1085dd 100644 --- a/src/lib/appManagers/internalLink.ts +++ b/src/lib/appManagers/internalLink.ts @@ -11,10 +11,11 @@ export enum INTERNAL_LINK_TYPE { JOIN_CHAT, VOICE_CHAT, USER_PHONE_NUMBER, - INVOICE + INVOICE, + EMOJI_SET }; -export type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber | InternalLink.InternalLinkInvoice; +export type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber | InternalLink.InternalLinkInvoice | InternalLink.InternalLinkEmojiSet; export namespace InternalLink { export interface InternalLinkMessage { @@ -62,6 +63,11 @@ export namespace InternalLink { _: INTERNAL_LINK_TYPE.INVOICE, slug: string } + + export interface InternalLinkEmojiSet { + _: INTERNAL_LINK_TYPE.EMOJI_SET, + set: string + } } export type InternalLinkTypeMap = { @@ -71,5 +77,6 @@ export type InternalLinkTypeMap = { [INTERNAL_LINK_TYPE.JOIN_CHAT]: InternalLink.InternalLinkJoinChat, [INTERNAL_LINK_TYPE.VOICE_CHAT]: InternalLink.InternalLinkVoiceChat, [INTERNAL_LINK_TYPE.USER_PHONE_NUMBER]: InternalLink.InternalLinkUserPhoneNumber, - [INTERNAL_LINK_TYPE.INVOICE]: InternalLink.InternalLinkInvoice + [INTERNAL_LINK_TYPE.INVOICE]: InternalLink.InternalLinkInvoice, + [INTERNAL_LINK_TYPE.EMOJI_SET]: InternalLink.InternalLinkEmojiSet }; diff --git a/src/lib/richTextProcessor/wrapUrl.ts b/src/lib/richTextProcessor/wrapUrl.ts index 230e27481..7dba24ab8 100644 --- a/src/lib/richTextProcessor/wrapUrl.ts +++ b/src/lib/richTextProcessor/wrapUrl.ts @@ -5,39 +5,42 @@ */ import {PHONE_NUMBER_REG_EXP} from '.'; +import {MOUNT_CLASS_TO} from '../../config/debug'; import matchUrlProtocol from './matchUrlProtocol'; -export default function wrapUrl(url: string, unsafe?: number | boolean): {url: string, onclick: string} { +export default function wrapUrl(url: string, unsafe?: number | boolean) { if(!matchUrlProtocol(url)) { url = 'https://' + url; } + const out: {url: string, onclick?: string, onclickUrl?: string} = {url}; let tgMeMatch, telescoPeMatch, tgMatch; - let onclick: string; + let onclick: string, onclickUrl: string; /* if(unsafe === 2) { url = 'tg://unsafe_url?url=' + encodeURIComponent(url); - } else */if((tgMeMatch = url.match(/^(?:https?:\/\/)?t(?:elegram)?\.me\/(.+)/))) { - const fullPath = tgMeMatch[1]; + } else */if((tgMeMatch = url.match(/^(?:https?:\/\/)?(?:(.+?)\.)?t(?:elegram)?\.me(?:\/(.+))?/))) { + const u = new URL(url); + if(tgMeMatch[1]) { + u.pathname = tgMeMatch[1] + (u.pathname === '/' ? '' : u.pathname); + } + + const fullPath = u.pathname.slice(1); const path = fullPath.split('/'); if(path[0] && path[0][0] === '$' && path[0].length > 1) { onclick = 'invoice'; - return {url, onclick}; - } - - // second regexp is for phone numbers (t.me/+38050...) - if(/^\W/.test(fullPath) && !PHONE_NUMBER_REG_EXP.test(fullPath)) { + } else if(/^\W/.test(fullPath) && !PHONE_NUMBER_REG_EXP.test(fullPath)) { // second regexp is for phone numbers (t.me/+38050...) onclick = 'joinchat'; - return {url, onclick}; - } - - switch(path[0]) { + } else switch(path[0]) { case 'joinchat': case 'addstickers': + case 'addemoji': case 'voicechat': case 'invoice': - onclick = path[0]; - break; + if(path.length !== 1) { + onclick = path[0]; + break; + } default: if((path[1] && path[1].match(/^\d+(?:\?(?:comment|thread)=\d+)?$/)) || path.length === 1) { @@ -59,5 +62,8 @@ export default function wrapUrl(url: string, unsafe?: number | boolean): {url: s onclick = undefined; } - return {url, onclick}; + out.onclick = onclick; + return out; } + +MOUNT_CLASS_TO && (MOUNT_CLASS_TO.wrapUrl = wrapUrl);