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.
636 lines
20 KiB
636 lines
20 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import type AppMediaViewerBase from '../../components/appMediaViewerBase'; |
|
import PopupElement from '../../components/popups'; |
|
import PopupSharedFolderInvite from '../../components/popups/sharedFolderInvite'; |
|
import PopupJoinChatInvite from '../../components/popups/joinChatInvite'; |
|
import PopupPayment from '../../components/popups/payment'; |
|
import PopupPeer from '../../components/popups/peer'; |
|
import PopupPickUser from '../../components/popups/pickUser'; |
|
import PopupStickers from '../../components/popups/stickers'; |
|
import {toastNew, toast} from '../../components/toast'; |
|
import {MOUNT_CLASS_TO} from '../../config/debug'; |
|
import IS_GROUP_CALL_SUPPORTED from '../../environment/groupCallSupport'; |
|
import addAnchorListener from '../../helpers/addAnchorListener'; |
|
import assumeType from '../../helpers/assumeType'; |
|
import findUpClassName from '../../helpers/dom/findUpClassName'; |
|
import {ChatInvite, User, AttachMenuPeerType, MessagesBotApp, BotApp, ChatlistsChatlistInvite} from '../../layer'; |
|
import {i18n, LangPackKey, _i18n} from '../langPack'; |
|
import {PHONE_NUMBER_REG_EXP} from '../richTextProcessor'; |
|
import {isWebAppNameValid} from '../richTextProcessor/validators'; |
|
import appImManager from './appImManager'; |
|
import {INTERNAL_LINK_TYPE, InternalLinkTypeMap, InternalLink} from './internalLink'; |
|
import {AppManagers} from './managers'; |
|
|
|
export class InternalLinkProcessor { |
|
protected managers: AppManagers; |
|
|
|
public construct(managers: AppManagers) { |
|
this.managers = managers; |
|
|
|
addAnchorListener<{}>({ |
|
name: 'showMaskedAlert', |
|
callback: (params, element) => { |
|
const href = element.href; |
|
|
|
const a = element.cloneNode(true) as HTMLAnchorElement; |
|
a.className = 'anchor-url'; |
|
a.innerText = href; |
|
a.removeAttribute('onclick'); |
|
|
|
const popup = PopupElement.createPopup(PopupPeer, 'popup-masked-url', { |
|
titleLangKey: 'OpenUrlTitle', |
|
descriptionLangKey: 'OpenUrlAlert2', |
|
descriptionLangArgs: [a], |
|
buttons: [{ |
|
langKey: 'Open', |
|
callback: () => { |
|
a.click(); |
|
} |
|
}] |
|
}) |
|
|
|
popup.show(); |
|
return popup; |
|
} |
|
}); |
|
|
|
addAnchorListener<{uriParams: {command: string, bot: string}}>({ |
|
name: 'execBotCommand', |
|
callback: ({uriParams}) => { |
|
const {command, bot} = uriParams; |
|
|
|
/* const promise = bot ? this.openUsername(bot).then(() => this.chat.peerId) : Promise.resolve(this.chat.peerId); |
|
promise.then((peerId) => { |
|
this.managers.appMessagesManager.sendText(peerId, '/' + command); |
|
}); */ |
|
|
|
return this.managers.appMessagesManager.sendText(appImManager.chat.peerId, '/' + command + (bot ? '@' + bot : '')); |
|
} |
|
}); |
|
|
|
addAnchorListener<{uriParams: {hashtag: string}}>({ |
|
name: 'searchByHashtag', |
|
callback: ({uriParams}) => { |
|
const {hashtag} = uriParams; |
|
if(!hashtag) { |
|
return; |
|
} |
|
|
|
return appImManager.chat.initSearch('#' + hashtag + ' '); |
|
} |
|
}); |
|
|
|
addAnchorListener<{}>({ |
|
name: 'setMediaTimestamp', |
|
callback: (_, element) => { |
|
const timestamp = +element.dataset.timestamp; |
|
const bubble = findUpClassName(element, 'bubble'); |
|
if(bubble) { |
|
appImManager.chat.bubbles.playMediaWithTimestamp(element, timestamp); |
|
return; |
|
} |
|
|
|
if(findUpClassName(element, 'media-viewer-caption')) { |
|
const appMediaViewer = (window as any).appMediaViewer as AppMediaViewerBase<any, any, any>; |
|
return appMediaViewer.setMediaTimestamp(timestamp); |
|
} |
|
} |
|
}); |
|
|
|
([ |
|
['addstickers', INTERNAL_LINK_TYPE.STICKER_SET], |
|
['addemoji', INTERNAL_LINK_TYPE.EMOJI_SET] |
|
] as [ |
|
'addstickers' | 'addemoji', |
|
INTERNAL_LINK_TYPE.STICKER_SET | INTERNAL_LINK_TYPE.EMOJI_SET |
|
][]).forEach(([name, type]) => { |
|
addAnchorListener<{pathnameParams: [typeof name, string]}>({ |
|
name, |
|
callback: ({pathnameParams}) => { |
|
if(!pathnameParams[1]) { |
|
return; |
|
} |
|
|
|
const link: InternalLink = { |
|
_: type, |
|
set: pathnameParams[1] |
|
}; |
|
|
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
addAnchorListener<{ |
|
uriParams: { |
|
set: string |
|
} |
|
}>({ |
|
name, |
|
protocol: 'tg', |
|
callback: ({uriParams}) => { |
|
const link = this.makeLink(type, uriParams); |
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
}); |
|
|
|
// * t.me/invoice/asdasdad |
|
// * t.me/$asdasdad |
|
addAnchorListener<{pathnameParams: ['invoice', string] | string}>({ |
|
name: 'invoice', |
|
callback: ({pathnameParams}) => { |
|
const link: InternalLink = { |
|
_: INTERNAL_LINK_TYPE.INVOICE, |
|
slug: pathnameParams.length > 1 ? pathnameParams[1] : pathnameParams[0].slice(1) |
|
}; |
|
|
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
// t.me/addlist/adasdasd |
|
addAnchorListener<{pathnameParams: ['folder', string]}>({ |
|
name: 'addlist', |
|
callback: ({pathnameParams}) => { |
|
const link: InternalLink = { |
|
_: INTERNAL_LINK_TYPE.ADD_LIST, |
|
slug: pathnameParams[1] |
|
}; |
|
|
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
// Support old t.me/joinchat/asd and new t.me/+asd |
|
addAnchorListener<{pathnameParams: ['joinchat', string]}>({ |
|
name: 'joinchat', |
|
callback: ({pathnameParams}) => { |
|
const link: InternalLink = { |
|
_: INTERNAL_LINK_TYPE.JOIN_CHAT, |
|
invite: pathnameParams[1] || decodeURIComponent(pathnameParams[0]).slice(1) |
|
}; |
|
|
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
if(IS_GROUP_CALL_SUPPORTED) { |
|
addAnchorListener<{ |
|
uriParams: Omit<InternalLink.InternalLinkVoiceChat, '_'> |
|
}>({ |
|
name: 'voicechat', |
|
protocol: 'tg', |
|
callback: ({uriParams}) => { |
|
const link = this.makeLink(INTERNAL_LINK_TYPE.VOICE_CHAT, uriParams); |
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
} |
|
|
|
type K1 = {thread?: string, comment?: string, t?: string}; |
|
type K2 = {thread?: string, comment?: string, start?: string, t?: string}; |
|
type K3 = {startattach?: string, attach?: string, choose?: TelegramChoosePeerType}; |
|
type K4 = {startapp?: string}; |
|
|
|
addAnchorListener<{ |
|
// pathnameParams: ['c', string, string], |
|
// uriParams: {thread?: number} |
|
// } | { |
|
// pathnameParams: [string, string?], |
|
// uriParams: {comment?: number} |
|
pathnameParams: ['c', string, string] | [string, string?], |
|
uriParams: K1 | K2 | K3 | K4 |
|
}>({ |
|
name: 'im', |
|
callback: async({pathnameParams, uriParams}, element, masked) => { |
|
let link: InternalLink; |
|
if(PHONE_NUMBER_REG_EXP.test(pathnameParams[0])) { |
|
link = { |
|
_: INTERNAL_LINK_TYPE.USER_PHONE_NUMBER, |
|
phone: pathnameParams[0].slice(1) |
|
}; |
|
} else if(pathnameParams[0] === 'c') { |
|
assumeType<K1>(uriParams); |
|
pathnameParams.shift(); |
|
const thread = 'thread' in uriParams ? uriParams.thread : pathnameParams[2] && pathnameParams[1]; |
|
link = { |
|
_: INTERNAL_LINK_TYPE.PRIVATE_POST, |
|
channel: pathnameParams[0], |
|
post: pathnameParams[2] || pathnameParams[1], |
|
thread, |
|
comment: uriParams.comment, |
|
stack: appImManager.getStackFromElement(element), |
|
t: uriParams.t |
|
}; |
|
} else if(pathnameParams[1] && isWebAppNameValid(pathnameParams[1])) { |
|
assumeType<K4>(uriParams); |
|
link = { |
|
_: INTERNAL_LINK_TYPE.WEB_APP, |
|
domain: pathnameParams[0], |
|
appname: pathnameParams[1], |
|
startapp: uriParams.startapp, |
|
masked |
|
}; |
|
} else { |
|
assumeType<K2>(uriParams); |
|
const thread = 'thread' in uriParams ? uriParams.thread : pathnameParams[2] && pathnameParams[1]; |
|
link = { |
|
_: INTERNAL_LINK_TYPE.MESSAGE, |
|
domain: pathnameParams[0], |
|
post: pathnameParams[2] || pathnameParams[1], |
|
thread, |
|
comment: uriParams.comment, |
|
start: 'start' in uriParams ? uriParams.start : undefined, |
|
stack: appImManager.getStackFromElement(element), |
|
t: uriParams.t |
|
}; |
|
} |
|
|
|
if('startattach' in uriParams || 'attach' in uriParams) { |
|
assumeType<K3>(uriParams); |
|
link = { |
|
_: INTERNAL_LINK_TYPE.ATTACH_MENU_BOT, |
|
nestedLink: link, |
|
...uriParams |
|
}; |
|
} |
|
|
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
addAnchorListener<{ |
|
uriParams: { |
|
domain: string, |
|
|
|
// telegrampassport |
|
scope?: string, |
|
nonce?: string, |
|
payload?: string, |
|
bot_id?: string, |
|
public_key?: string, |
|
callback_url?: string, |
|
|
|
// regular |
|
start?: string, |
|
startgroup?: string, |
|
game?: string, |
|
voicechat?: string, |
|
post?: string, |
|
thread?: string, |
|
comment?: string, |
|
phone?: string, |
|
t?: string, |
|
attach?: string, |
|
startattach?: string, |
|
choose?: TelegramChoosePeerType, |
|
appname?: string, |
|
startapp?: string |
|
} |
|
}>({ |
|
name: 'resolve', |
|
protocol: 'tg', |
|
callback: ({uriParams}, element, masked) => { |
|
let link: InternalLink; |
|
if(uriParams.phone) { |
|
link = this.makeLink(INTERNAL_LINK_TYPE.USER_PHONE_NUMBER, uriParams as Required<typeof uriParams>); |
|
} else if(uriParams.domain === 'telegrampassport') { |
|
|
|
} else if(uriParams.appname) { |
|
link = this.makeLink(INTERNAL_LINK_TYPE.WEB_APP, { |
|
masked, |
|
...uriParams as Required<typeof uriParams> |
|
}); |
|
} else { |
|
link = this.makeLink(INTERNAL_LINK_TYPE.MESSAGE, { |
|
...uriParams, |
|
stack: appImManager.getStackFromElement(element) |
|
}); |
|
} |
|
|
|
if(uriParams.attach !== undefined || uriParams.startattach !== undefined) { |
|
const nestedLink = link; |
|
link = this.makeLink(INTERNAL_LINK_TYPE.ATTACH_MENU_BOT, uriParams as Required<typeof uriParams>); |
|
link.nestedLink = nestedLink; |
|
} |
|
|
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
addAnchorListener<{ |
|
uriParams: { |
|
channel: string, |
|
post: string, |
|
thread?: string, |
|
comment?: string |
|
} |
|
}>({ |
|
name: 'privatepost', |
|
protocol: 'tg', |
|
callback: ({uriParams}) => { |
|
const link = this.makeLink(INTERNAL_LINK_TYPE.PRIVATE_POST, uriParams); |
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
// tg://invoice?slug=asdasd |
|
addAnchorListener<{ |
|
uriParams: { |
|
slug: string |
|
} |
|
}>({ |
|
name: 'invoice', |
|
protocol: 'tg', |
|
callback: ({uriParams}) => { |
|
const link = this.makeLink(INTERNAL_LINK_TYPE.INVOICE, uriParams); |
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
// tg://addlist?slug=asd |
|
addAnchorListener<{ |
|
uriParams: { |
|
slug: string |
|
} |
|
}>({ |
|
name: 'addlist', |
|
protocol: 'tg', |
|
callback: ({uriParams}) => { |
|
const link = this.makeLink(INTERNAL_LINK_TYPE.ADD_LIST, uriParams); |
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
|
|
['joinchat' as const, 'join' as const].forEach((name) => { |
|
addAnchorListener<{ |
|
uriParams: { |
|
invite: string |
|
} |
|
}>({ |
|
name, |
|
protocol: 'tg', |
|
callback: ({uriParams}) => { |
|
const link = this.makeLink(INTERNAL_LINK_TYPE.JOIN_CHAT, uriParams); |
|
return this.processInternalLink(link); |
|
} |
|
}); |
|
}); |
|
} |
|
|
|
private makeLink<T extends INTERNAL_LINK_TYPE>(type: T, uriParams: Omit<InternalLinkTypeMap[T], '_'>) { |
|
return { |
|
_: type, |
|
...uriParams |
|
} as any as InternalLinkTypeMap[T]; |
|
} |
|
|
|
public processMessageLink = (link: InternalLink.InternalLinkMessage) => { |
|
const postId = link.post ? +link.post : undefined; |
|
const commentId = link.comment ? +link.comment : undefined; |
|
const threadId = link.thread ? +link.thread : undefined; |
|
|
|
return appImManager.openUsername({ |
|
userName: link.domain, |
|
lastMsgId: postId, |
|
commentId, |
|
startParam: link.start, |
|
stack: link.stack, |
|
threadId, |
|
mediaTimestamp: link.t && +link.t |
|
}); |
|
}; |
|
|
|
public processPrivatePostLink = async(link: InternalLink.InternalLinkPrivatePost) => { |
|
const chatId = link.channel.toChatId(); |
|
|
|
const chat = await this.managers.appChatsManager.getChat(chatId); |
|
if(!chat) { |
|
try { |
|
await this.managers.appChatsManager.resolveChannel(chatId); |
|
} catch(err) { |
|
toastNew({langPackKey: 'LinkNotFound'}); |
|
throw err; |
|
} |
|
} |
|
|
|
const postId = +link.post; |
|
const threadId = link.thread ? +link.thread : undefined; |
|
|
|
return appImManager.op({ |
|
peer: chat, |
|
lastMsgId: postId, |
|
threadId, |
|
stack: link.stack, |
|
mediaTimestamp: link.t && +link.t |
|
}); |
|
}; |
|
|
|
public processStickerSetLink = (link: InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkEmojiSet) => { |
|
const popup = PopupElement.createPopup(PopupStickers, {id: link.set}, link._ === INTERNAL_LINK_TYPE.EMOJI_SET); |
|
popup.show(); |
|
return popup; |
|
}; |
|
|
|
public processJoinChatLink = (link: InternalLink.InternalLinkJoinChat) => { |
|
return this.managers.appChatsManager.checkChatInvite(link.invite).then((chatInvite) => { |
|
if((chatInvite as ChatInvite.chatInvitePeek).chat) { |
|
this.managers.appChatsManager.saveApiChat((chatInvite as ChatInvite.chatInvitePeek).chat, true); |
|
} |
|
|
|
// console.log(chatInvite); |
|
|
|
if(chatInvite._ === 'chatInviteAlready' || |
|
chatInvite._ === 'chatInvitePeek'/* && chatInvite.expires > tsNow(true) */) { |
|
appImManager.setInnerPeer({ |
|
peerId: chatInvite.chat.id.toPeerId(true) |
|
}); |
|
return; |
|
} |
|
|
|
return PopupElement.createPopup(PopupJoinChatInvite, link.invite, chatInvite); |
|
}, (err: ApiError) => { |
|
if(err.type === 'INVITE_HASH_EXPIRED') { |
|
toast(i18n('InviteExpired')); |
|
} |
|
}); |
|
}; |
|
|
|
public processVoiceChatLink = (link: InternalLink.InternalLinkVoiceChat) => { |
|
if(IS_GROUP_CALL_SUPPORTED) { |
|
return appImManager.joinGroupCall(link.chat_id.toPeerId(true), link.id); |
|
} |
|
}; |
|
|
|
public processUserPhoneNumberLink = (link: InternalLink.InternalLinkUserPhoneNumber) => { |
|
return this.managers.appUsersManager.resolvePhone(link.phone).then((user) => { |
|
return appImManager.setInnerPeer({ |
|
peerId: user.id.toPeerId(false) |
|
}); |
|
}).catch((err: ApiError) => { |
|
if(err.type === 'PHONE_NOT_OCCUPIED') { |
|
toastNew({langPackKey: 'Alert.UserDoesntExists'}); |
|
} |
|
}); |
|
}; |
|
|
|
public processInvoiceLink = (link: InternalLink.InternalLinkInvoice) => { |
|
return this.managers.appPaymentsManager.getInputInvoiceBySlug(link.slug).then((inputInvoice) => { |
|
return this.managers.appPaymentsManager.getPaymentForm(inputInvoice).then((paymentForm) => { |
|
// const message: Message.message = { |
|
// _: 'message', |
|
// date: 0, |
|
// id: 0, |
|
// peerId: 0, |
|
// peer_id: undefined, |
|
// message: '', |
|
// media: { |
|
// _: 'messageMediaInvoice', |
|
// currency: paymentForm.invoice.currency, |
|
// description: paymentForm.description, |
|
|
|
// } |
|
// }; |
|
return PopupElement.createPopup(PopupPayment, undefined, inputInvoice, paymentForm); |
|
}); |
|
}); |
|
}; |
|
|
|
public processAttachMenuBotLink = async(link: InternalLink.InternalLinkAttachMenuBot) => { |
|
const botUsername = link.attach || link.domain || (link.nestedLink as InternalLink.InternalLinkMessage).domain; |
|
const user = await this.managers.appUsersManager.resolveUserByUsername(botUsername).catch(() => undefined as User.user); |
|
|
|
let processInternalLinkResult: any; |
|
if(link.attach !== undefined) { |
|
processInternalLinkResult = this.processInternalLink(link.nestedLink); |
|
} |
|
|
|
let errorLangPackKey: LangPackKey; |
|
if(!user) { |
|
errorLangPackKey = 'Alert.UserDoesntExists'; |
|
} else if(!user.pFlags.bot_attach_menu) { |
|
errorLangPackKey = 'BotCantAddToAttachMenu'; |
|
}/* else if(user.pFlags.attach_menu_enabled) { |
|
errorLangPackKey = 'BotAlreadyAddedToAttachMenu'; |
|
} */ |
|
|
|
if(errorLangPackKey) { |
|
toastNew({langPackKey: errorLangPackKey}); |
|
return; |
|
} |
|
|
|
processInternalLinkResult && await processInternalLinkResult; |
|
const attachMenuBot = await appImManager.toggleBotInAttachMenu(user.id, true); |
|
|
|
if(link.choose) { |
|
type ChooseType = typeof link['choose']; |
|
const choose = link.choose.split('+') as ChooseType[]; |
|
const verifyMap: { |
|
[type in ChooseType]: AttachMenuPeerType['_'] |
|
} = { |
|
bots: 'attachMenuPeerTypeBotPM', |
|
users: 'attachMenuPeerTypePM', |
|
groups: 'attachMenuPeerTypeChat', |
|
channels: 'attachMenuPeerTypeBroadcast' |
|
}; |
|
|
|
const filteredTypes = choose.filter((type) => { |
|
const peerTypePredicate = verifyMap[type]; |
|
return attachMenuBot.peer_types.some((peerType) => peerType._ === peerTypePredicate); |
|
}); |
|
|
|
const chosenPeerId = await PopupPickUser.createPicker(filteredTypes); |
|
await appImManager.setInnerPeer({peerId: chosenPeerId}); |
|
} |
|
|
|
appImManager.chat.openWebApp({attachMenuBot, startParam: link.startattach}); |
|
}; |
|
|
|
public processWebAppLink = async(link: InternalLink.InternalLinkWebApp) => { |
|
const user = await this.managers.appUsersManager.resolveUserByUsername(link.domain).catch(() => undefined as User.user); |
|
if(!user) { |
|
toastNew({langPackKey: 'Alert.UserDoesntExists'}); |
|
return; |
|
} |
|
|
|
const botId = user.id; |
|
|
|
let botApp: MessagesBotApp; |
|
try { |
|
botApp = await this.managers.appAttachMenuBotsManager.getBotApp(botId, link.appname); |
|
} catch(err) { |
|
if((err as ApiError).type === 'BOT_APP_INVALID') { |
|
toastNew({langPackKey: 'Alert.BotAppDoesntExist'}); |
|
return; |
|
} else { |
|
throw err; |
|
} |
|
} |
|
|
|
let haveWriteAccess: boolean; |
|
if(botApp.pFlags.inactive || link.masked) { |
|
haveWriteAccess = await appImManager.confirmBotWebViewInner(botId, botApp.pFlags.request_write_access); |
|
} |
|
|
|
appImManager.chat.openWebApp({ |
|
startParam: link.startapp, |
|
writeAllowed: haveWriteAccess, |
|
botId, |
|
app: botApp.app as BotApp.botApp |
|
}); |
|
}; |
|
|
|
public processListLink = async(link: InternalLink.InternalLinkAddList) => { |
|
let chatlistInvite: ChatlistsChatlistInvite; |
|
try { |
|
chatlistInvite = await this.managers.filtersStorage.checkChatlistInvite(link.slug); |
|
} catch(err) { |
|
if((err as ApiError).type === 'INVITE_SLUG_EXPIRED') { |
|
toastNew({langPackKey: 'SharedFolder.Link.Expired'}); |
|
return; |
|
} |
|
|
|
throw err; |
|
} |
|
|
|
PopupElement.createPopup(PopupSharedFolderInvite, { |
|
chatlistInvite, |
|
slug: link.slug |
|
}); |
|
}; |
|
|
|
public processInternalLink(link: InternalLink) { |
|
const map: { |
|
[key in InternalLink['_']]?: (link: any) => any |
|
} = { |
|
[INTERNAL_LINK_TYPE.MESSAGE]: this.processMessageLink, |
|
[INTERNAL_LINK_TYPE.PRIVATE_POST]: this.processPrivatePostLink, |
|
[INTERNAL_LINK_TYPE.EMOJI_SET]: this.processStickerSetLink, |
|
[INTERNAL_LINK_TYPE.STICKER_SET]: this.processStickerSetLink, |
|
[INTERNAL_LINK_TYPE.JOIN_CHAT]: this.processJoinChatLink, |
|
[INTERNAL_LINK_TYPE.VOICE_CHAT]: this.processVoiceChatLink, |
|
[INTERNAL_LINK_TYPE.USER_PHONE_NUMBER]: this.processUserPhoneNumberLink, |
|
[INTERNAL_LINK_TYPE.INVOICE]: this.processInvoiceLink, |
|
[INTERNAL_LINK_TYPE.ATTACH_MENU_BOT]: this.processAttachMenuBotLink, |
|
[INTERNAL_LINK_TYPE.WEB_APP]: this.processWebAppLink, |
|
[INTERNAL_LINK_TYPE.ADD_LIST]: this.processListLink |
|
}; |
|
|
|
const processor = map[link._]; |
|
if(!processor) { |
|
console.warn('Not supported internal link:', link); |
|
return; |
|
} |
|
|
|
return processor(link); |
|
} |
|
} |
|
|
|
const internalLinkProcessor = new InternalLinkProcessor(); |
|
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.internalLinkProcessor = internalLinkProcessor); |
|
export default internalLinkProcessor;
|
|
|