diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 66722442..b0a64c7d 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -1141,7 +1141,7 @@ export default class ChatBubbles { if(hadRights !== hasRights || hadPlainRights !== hasPlainRights) { const callbacks = await Promise.all([ this.finishPeerChange(), - this.chat.input.finishPeerChange() + this.chat.input.finishPeerChange({middleware: this.getMiddleware()}) ]); callbacks.forEach((callback) => callback()); @@ -3184,10 +3184,17 @@ export default class ChatBubbles { log.warn('got history');// warning const {promise, cached} = result; + const finishPeerChangeOptions: Parameters[0] = { + isTarget, + isJump, + lastMsgId, + startParam, + middleware + }; if(!cached && !samePeer) { - await m(this.chat.finishPeerChange(isTarget, isJump, lastMsgId, startParam)); - this.scrollable.container.textContent = ''; + await m(this.chat.finishPeerChange(finishPeerChangeOptions)); + this.scrollable.container.replaceChildren(); // oldContainer.textContent = ''; // oldChatInner.remove(); this.preloader.attach(this.container); @@ -3203,7 +3210,7 @@ export default class ChatBubbles { const mountedByLastMsgId = haveToScrollToBubble ? await m(lastMsgId ? this.getMountedBubble(lastMsgId) : {bubble: this.getLastBubble()}) : undefined; if(cached && !samePeer) { log.warn('finishing peer change'); - await m(this.chat.finishPeerChange(isTarget, isJump, lastMsgId, startParam)); // * костыль + await m(this.chat.finishPeerChange(finishPeerChangeOptions)); // * костыль log.warn('finished peer change'); } diff --git a/src/components/chat/chat.ts b/src/components/chat/chat.ts index 15e195fa..b6a94f2e 100644 --- a/src/components/chat/chat.ts +++ b/src/components/chat/chat.ts @@ -580,23 +580,29 @@ export default class Chat extends EventListenerBase<{ }); } - public async finishPeerChange(isTarget: boolean, isJump: boolean, lastMsgId: number, startParam?: string) { + public async finishPeerChange(options: { + isTarget?: boolean, + isJump?: boolean, + lastMsgId?: number, + startParam?: string, + middleware: () => boolean + }) { if(this.peerChanged) return; const peerId = this.peerId; this.peerChanged = true; this.wasAlreadyUsed = true; - const middleware = this.bubbles.getMiddleware(); + const {middleware} = options; this.cleanup(false); const sharedMediaTab = this.sharedMediaTab; const callbacksPromise = Promise.all([ - this.topbar.finishPeerChange(isTarget), + this.topbar.finishPeerChange(options), this.bubbles.finishPeerChange(), - this.input.finishPeerChange(startParam), + this.input.finishPeerChange(options), sharedMediaTab.fillProfileElements() ]); diff --git a/src/components/chat/input.ts b/src/components/chat/input.ts index 4849022e..76d930c4 100644 --- a/src/components/chat/input.ts +++ b/src/components/chat/input.ts @@ -648,7 +648,7 @@ export default class ChatInput { icon: 'gift', text: 'GiftPremium', onClick: () => this.chat.appImManager.giftPremium(this.chat.peerId), - verify: async() => await this.chat.canGiftPremium() && (await this.managers.apiManager.getAppConfig()).premium_gift_attach_menu_icon + verify: () => Promise.all([this.chat.canGiftPremium(), this.managers.apiManager.getAppConfig()]).then(([canGift, {premium_gift_attach_menu_icon}]) => canGift && premium_gift_attach_menu_icon) }, { icon: 'poll', text: 'Poll', @@ -676,6 +676,7 @@ export default class ChatInput { onOpenBefore: async() => { const attachMenuBots = await this.managers.appAttachMenuBotsManager.getAttachMenuBots(); const buttons = attachMenuButtons.slice(); + console.log(attachMenuBots); const attachMenuBotsButtons = attachMenuBots.filter((attachMenuBot) => { return !attachMenuBot.pFlags.inactive; }).map((attachMenuBot) => { @@ -693,8 +694,8 @@ export default class ChatInput { 'allow-same-origin', 'allow-popups', 'allow-forms', - 'allow-modals', - 'allow-storage-access-by-user-activation' + 'allow-modals' + // 'allow-storage-access-by-user-activation' ].join(' '); class P extends PopupElement<{ @@ -1407,13 +1408,24 @@ export default class ChatInput { return this.sendAs; } - public async finishPeerChange(startParam?: string) { + public async finishPeerChange(options: Parameters[0]) { const peerId = this.chat.peerId; + const {startParam, middleware} = options; - const {forwardElements, btnScheduled, replyKeyboard, sendMenu, goDownBtn, chatInput, botCommandsToggle} = this; + const { + forwardElements, + btnScheduled, + replyKeyboard, + sendMenu, + goDownBtn, + chatInput, + botCommandsToggle, + attachMenu + } = this; const previousSendAs = this.sendAs; const sendAs = this.createSendAs(); + const filteredAttachMenuButtons = this.filterAttachMenuButtons(); const [ isBroadcast, @@ -1424,8 +1436,7 @@ export default class ChatInput { neededFakeContainer, ackedPeerFull, ackedScheduledMids, - setSendAsCallback, - filteredAttachMenuButtons + setSendAsCallback ] = await Promise.all([ this.managers.appPeersManager.isBroadcast(peerId), this.managers.appPeersManager.canPinMessage(peerId), @@ -1435,8 +1446,7 @@ export default class ChatInput { this.getNeededFakeContainer(startParam), modifyAckedPromise(this.managers.acknowledged.appProfileManager.getProfileByPeerId(peerId)), btnScheduled ? modifyAckedPromise(this.managers.acknowledged.appMessagesManager.getScheduledMessages(peerId)) : undefined, - sendAs ? (sendAs.setPeerId(this.chat.peerId), sendAs.updateManual(true)) : undefined, - this.filterAttachMenuButtons() + sendAs ? (sendAs.setPeerId(this.chat.peerId), sendAs.updateManual(true)) : undefined ]); const placeholderKey = this.messageInput ? await this.getPlaceholderKey(canSendPlain) : undefined; @@ -1466,7 +1476,6 @@ export default class ChatInput { if(btnScheduled && ackedScheduledMids) { btnScheduled.classList.add('hide'); - const middleware = this.chat.bubbles.getMiddleware(); callbackify(ackedScheduledMids.result, (mids) => { if(!middleware() || !mids) return; btnScheduled.classList.toggle('hide', !mids.length); @@ -1483,7 +1492,6 @@ export default class ChatInput { this.updateBotCommandsToggle(true); botCommandsToggle.remove(); if(isBot) { - const middleware = this.chat.bubbles.getMiddleware(); const result = ackedPeerFull.result; callbackify(result, (userFull) => { if(!middleware()) return; @@ -1498,8 +1506,19 @@ export default class ChatInput { sendMenu?.setPeerId(peerId); if(this.messageInput) { - this.updateMessageInput(canSend, canSendPlain, placeholderKey, filteredAttachMenuButtons); + this.updateMessageInput(canSend, canSendPlain, placeholderKey); this.messageInput.dataset.peerId = '' + peerId; + + if(filteredAttachMenuButtons && attachMenu) { + filteredAttachMenuButtons.then((visible) => { + if(!middleware()) { + return; + } + + attachMenu.toggleAttribute('disabled', !visible.length); + attachMenu.classList.toggle('btn-disabled', !visible.length); + }); + } } this.messageInputField?.onFakeInput(undefined, true); @@ -1619,10 +1638,9 @@ export default class ChatInput { public updateMessageInput( canSend: boolean, canSendPlain: boolean, - placeholderKey: LangPackKey, - visible: ChatInput['attachMenuButtons'] + placeholderKey: LangPackKey ) { - const {chatInput, attachMenu, messageInput} = this; + const {chatInput, messageInput} = this; const isHidden = chatInput.classList.contains('is-hidden'); const willBeHidden = !canSend; if(isHidden !== willBeHidden) { @@ -1657,11 +1675,6 @@ export default class ChatInput { } } - if(attachMenu) { - attachMenu.toggleAttribute('disabled', !visible.length); - attachMenu.classList.toggle('btn-disabled', !visible.length); - } - this.updateSendBtn(); } diff --git a/src/components/chat/topbar.ts b/src/components/chat/topbar.ts index 65c8d334..feb01fc3 100644 --- a/src/components/chat/topbar.ts +++ b/src/components/chat/topbar.ts @@ -719,7 +719,7 @@ export default class ChatTopbar { } } - public async finishPeerChange(isTarget: boolean) { + public async finishPeerChange(options: Parameters[0]) { const {peerId, threadId} = this.chat; let newAvatar: AvatarElement; @@ -731,7 +731,15 @@ export default class ChatTopbar { } } - const [isBroadcast, isAnyChat, chat, _, setTitleCallback, setStatusCallback, state] = await Promise.all([ + const [ + isBroadcast, + isAnyChat, + chat, + _, + setTitleCallback, + setStatusCallback, + state + ] = await Promise.all([ this.managers.appPeersManager.isBroadcast(peerId), this.managers.appPeersManager.isAnyChat(peerId), peerId.isAnyChat() ? this.managers.appChatsManager.getChat(peerId.toChatId()) : undefined, diff --git a/src/components/inputField.ts b/src/components/inputField.ts index f6b711c7..22a8e3da 100644 --- a/src/components/inputField.ts +++ b/src/components/inputField.ts @@ -166,7 +166,7 @@ let init = () => { let usePlainText = true; // @ts-ignore - let html: string = (e.originalEvent || e).clipboardData.getData('text/html'); + let html: string = (e.originalEvent || e).clipboardData.getData('text/html') || plainText; const filterEntity = (e: MessageEntity) => e._ === 'messageEntityEmoji' || (e._ === 'messageEntityLinebreak' && !noLinebreaks); if(noLinebreaks) { diff --git a/src/components/peerProfile.ts b/src/components/peerProfile.ts index 49fcf846..9551e664 100644 --- a/src/components/peerProfile.ts +++ b/src/components/peerProfile.ts @@ -640,7 +640,7 @@ export default class PeerProfile { return; } - return await m(this._setMoreDetails(peerId, peerFull)); + return m(this._setMoreDetails(peerId, peerFull)); }); if(result.cached && manual) { diff --git a/src/components/wrappers/messageActionTextNewUnsafe.ts b/src/components/wrappers/messageActionTextNewUnsafe.ts index 13f19657..1ee21675 100644 --- a/src/components/wrappers/messageActionTextNewUnsafe.ts +++ b/src/components/wrappers/messageActionTextNewUnsafe.ts @@ -313,6 +313,13 @@ export default async function wrapMessageActionTextNewUnsafe(options: WrapMessag } case 'messageActionBotAllowed': { + if(action.pFlags?.attach_menu) { + langPackKey = 'ActionAttachMenuBotAllowed'; + break; + } else if(!action.domain) { + break; + } + const anchorHTML = wrapRichText(action.domain, { entities: [{ _: 'messageEntityUrl', diff --git a/src/config/app.ts b/src/config/app.ts index c3e45151..4d140f27 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -21,7 +21,7 @@ const App = { version: process.env.VERSION, versionFull: process.env.VERSION_FULL, build: +process.env.BUILD, - langPackVersion: '1.0.5', + langPackVersion: '1.0.7', langPack: 'webk', langPackCode: 'en', domains: MAIN_DOMAINS, diff --git a/src/helpers/dom/getRichElementValue.ts b/src/helpers/dom/getRichElementValue.ts index 772f3dde..8de6a4f6 100644 --- a/src/helpers/dom/getRichElementValue.ts +++ b/src/helpers/dom/getRichElementValue.ts @@ -212,7 +212,7 @@ export default function getRichElementValue( const isSelected = selNode === node; const isBlock = BLOCK_TAGS.has(node.tagName); - if(isBlock && (line.length || node.tagName === 'BR'/* || (BLOCK_TAGS.has(node.tagName) && lines.length) */)) { + if(isBlock && ((line.length && line[line.length - 1].slice(-1) !== '\n') || node.tagName === 'BR'/* || (BLOCK_TAGS.has(node.tagName) && lines.length) */)) { pushLine(); } else { const alt = node.dataset.stickerEmoji || (node as HTMLImageElement).alt; diff --git a/src/helpers/dom/setInnerHTML.ts b/src/helpers/dom/setInnerHTML.ts index c8f98477..20e412bd 100644 --- a/src/helpers/dom/setInnerHTML.ts +++ b/src/helpers/dom/setInnerHTML.ts @@ -8,7 +8,9 @@ export default function setInnerHTML(elem: Element, html: string | DocumentFragment | Element) { setDirection(elem); - if(typeof(html) === 'string') { + if(html === undefined) { + elem.replaceChildren(); + } else if(typeof(html) === 'string') { if(!html) elem.replaceChildren(); else elem.textContent = html; } else { diff --git a/src/helpers/string/parseUriParams.ts b/src/helpers/string/parseUriParams.ts index 1f013438..44b5ca64 100644 --- a/src/helpers/string/parseUriParams.ts +++ b/src/helpers/string/parseUriParams.ts @@ -15,7 +15,8 @@ export function parseUriParamsLine(line: string) { } line.split('&').forEach((item) => { - params[item.split('=')[0]] = decodeURIComponent(item.split('=')[1]); + const [key, value = ''] = item.split('='); + params[key] = decodeURIComponent(value); }); return params; diff --git a/src/lang.ts b/src/lang.ts index 3cfe71a2..b568a123 100644 --- a/src/lang.ts +++ b/src/lang.ts @@ -950,6 +950,11 @@ const lang = { 'ActionGiftPremiumTitle': 'Telegram Premium', 'ActionGiftPremiumSubtitle': 'for %1$s', 'ChatAdmin': 'admin', + 'BotRequestAttachPermission': '**%1$s** requests to be added as an option to your attachment menu so you can access it from any chat.', + 'BotCantAddToAttachMenu': 'This bot can\'t be added to the attachment menu.', + 'BotAlreadyAddedToAttachMenu': 'This bot is already added to your attachment menu.', + 'AddBot': 'Add Bot', + 'ActionAttachMenuBotAllowed': 'You allowed this bot to message you when you added it to your attachment menu.', // * macos 'AccountSettings.Filters': 'Chat Folders', diff --git a/src/lib/appManagers/appAttachMenuBotsManager.ts b/src/lib/appManagers/appAttachMenuBotsManager.ts index b912c230..813b41f4 100644 --- a/src/lib/appManagers/appAttachMenuBotsManager.ts +++ b/src/lib/appManagers/appAttachMenuBotsManager.ts @@ -12,6 +12,8 @@ import makeError from '../../helpers/makeError'; import getAttachMenuBotIcon from './utils/attachMenuBots/getAttachMenuBotIcon'; import getServerMessageId from './utils/messageId/getServerMessageId'; +const BOTS_SUPPORTED = false; + export default class AppAttachMenuBotsManager extends AppManager { private attachMenuBots: Map; private attachMenuBotsArr: AttachMenuBot[]; @@ -58,8 +60,7 @@ export default class AppAttachMenuBotsManager extends AppManager { assumeType(attachMenuBots); this.appUsersManager.saveApiUsers(attachMenuBots.users); this.saveAttachMenuBots(attachMenuBots.bots); - // ! temporary - return this.attachMenuBotsArr = attachMenuBots.bots.slice(0, 0); + return this.attachMenuBotsArr = attachMenuBots.bots.slice(0, BOTS_SUPPORTED ? undefined : 0); } }); } @@ -69,7 +70,7 @@ export default class AppAttachMenuBotsManager extends AppManager { } public getAttachMenuBot(botId: BotId, overwrite?: boolean) { - if(!this.appUsersManager.isAttachMenuBot(botId) || true) { + if(!this.appUsersManager.isAttachMenuBot(botId) || !BOTS_SUPPORTED) { throw makeError('BOT_INVALID'); } @@ -154,4 +155,18 @@ export default class AppAttachMenuBotsManager extends AppManager { } }); } + + public toggleBotInAttachMenu(botId: BotId, enabled: boolean, writeAllowed?: boolean) { + return this.apiManager.invokeApiSingleProcess({ + method: 'messages.toggleBotInAttachMenu', + params: { + bot: this.appUsersManager.getUserInput(botId), + enabled, + write_allowed: writeAllowed + }, + processResult: () => { + this.apiUpdatesManager.processLocalUpdate({_: 'updateAttachMenuBots'}); + } + }); + } } diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 4e7025c8..423f6530 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -108,6 +108,8 @@ import indexOfAndSplice from '../../helpers/array/indexOfAndSplice'; import liteMode, {LiteModeKey} from '../../helpers/liteMode'; import RLottiePlayer from '../rlottie/rlottiePlayer'; import PopupGiftPremium from '../../components/popups/giftPremium'; +import assumeType from '../../helpers/assumeType'; +import noop from '../../helpers/noop'; export type ChatSavedPosition = { mids: number[], @@ -719,6 +721,10 @@ export class AppImManager extends EventListenerBase<{ }); } + 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?: string}; + addAnchorListener<{ // pathnameParams: ['c', string, string], // uriParams: {thread?: number} @@ -726,7 +732,7 @@ export class AppImManager extends EventListenerBase<{ // pathnameParams: [string, string?], // uriParams: {comment?: number} pathnameParams: ['c', string, string] | [string, string?], - uriParams: {thread?: string, comment?: string, t?: string} | {comment?: string, start?: string, t?: string} + uriParams: K1 | K2 | K3 }>({ name: 'im', callback: async({pathnameParams, uriParams}, element) => { @@ -737,6 +743,7 @@ export class AppImManager extends EventListenerBase<{ phone: pathnameParams[0].slice(1) }; } else if(pathnameParams[0] === 'c') { + assumeType(uriParams); pathnameParams.shift(); const thread = 'thread' in uriParams ? uriParams.thread : pathnameParams[2] && pathnameParams[1]; link = { @@ -749,6 +756,7 @@ export class AppImManager extends EventListenerBase<{ t: uriParams.t }; } else { + assumeType(uriParams); const thread = 'thread' in uriParams ? uriParams.thread : pathnameParams[2] && pathnameParams[1]; link = { _: INTERNAL_LINK_TYPE.MESSAGE, @@ -762,6 +770,15 @@ export class AppImManager extends EventListenerBase<{ }; } + if('startattach' in uriParams || 'attach' in uriParams) { + assumeType(uriParams); + link = { + _: INTERNAL_LINK_TYPE.ATTACH_MENU_BOT, + nestedLink: link, + ...uriParams + }; + } + this.processInternalLink(link); } }); @@ -787,7 +804,10 @@ export class AppImManager extends EventListenerBase<{ thread?: string, comment?: string, phone?: string, - t?: string + t?: string, + attach?: string, + startattach?: string, + choose?: string } }>({ name: 'resolve', @@ -805,6 +825,12 @@ export class AppImManager extends EventListenerBase<{ }); } + if(uriParams.attach !== undefined || uriParams.startattach !== undefined) { + const nestedLink = link; + link = this.makeLink(INTERNAL_LINK_TYPE.ATTACH_MENU_BOT, uriParams as Required); + link.nestedLink = nestedLink; + } + this.processInternalLink(link); } }); @@ -1265,6 +1291,56 @@ export class AppImManager extends EventListenerBase<{ break; } + case INTERNAL_LINK_TYPE.ATTACH_MENU_BOT: { + console.log(link); + const botUsername = link.attach || link.domain; + const user = await this.managers.appUsersManager.resolveUserByUsername(botUsername).catch(() => undefined as User.user); + + if(link.attach !== undefined) { + 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}); + break; + } + + const peerId = user.id.toPeerId(false); + const attachMenuBot = await this.managers.appAttachMenuBotsManager.getAttachMenuBot(user.id); + + console.log(attachMenuBot); + + if(attachMenuBot.pFlags.inactive) { + const haveWriteAccess = await confirmationPopup({ + button: { + text: 'Add' + }, + descriptionLangKey: 'BotRequestAttachPermission', + descriptionLangArgs: [await wrapPeerTitle({peerId})], + checkbox: attachMenuBot.pFlags.request_write_access ? { + text: 'OpenUrlOption2', + textArgs: [await wrapPeerTitle({peerId})], + checked: true + } : undefined, + peerId, + titleLangKey: 'AddBot' + }); + + await this.managers.appAttachMenuBotsManager.toggleBotInAttachMenu(user.id, true, haveWriteAccess); + } + + break; + } + default: { this.log.warn('Not supported internal link:', link); break; diff --git a/src/lib/appManagers/appReactionsManager.ts b/src/lib/appManagers/appReactionsManager.ts index d9fb5877..af288c7c 100644 --- a/src/lib/appManagers/appReactionsManager.ts +++ b/src/lib/appManagers/appReactionsManager.ts @@ -49,7 +49,8 @@ export class AppReactionsManager extends AppManager { this.rootScope.addEventListener('user_auth', () => { setTimeout(() => { Promise.resolve(this.getAvailableReactions()).then(async(availableReactions) => { - for(const availableReaction of availableReactions) { + for(let i = 0, length = availableReactions.length; i < length; ++i) { + const availableReaction = availableReactions[i]; await Promise.all([ availableReaction.around_animation && this.apiFileManager.downloadMedia({media: availableReaction.around_animation}), availableReaction.static_icon && this.apiFileManager.downloadMedia({media: availableReaction.static_icon}), @@ -57,6 +58,10 @@ export class AppReactionsManager extends AppManager { availableReaction.center_icon && this.apiFileManager.downloadMedia({media: availableReaction.center_icon}) ]); + if(i > 15) { + break; + } + await pause(1000); } }); diff --git a/src/lib/appManagers/appUsersManager.ts b/src/lib/appManagers/appUsersManager.ts index 89043c33..d9b7b860 100644 --- a/src/lib/appManagers/appUsersManager.ts +++ b/src/lib/appManagers/appUsersManager.ts @@ -28,6 +28,7 @@ import canSendToUser from './utils/users/canSendToUser'; import {AppStoragesManager} from './appStoragesManager'; import deepEqual from '../../helpers/object/deepEqual'; import getPeerActiveUsernames from './utils/peers/getPeerActiveUsernames'; +import callbackify from '../../helpers/callbackify'; export type User = MTUser.user; export type TopPeerType = 'correspondents' | 'bots_inline'; @@ -313,6 +314,12 @@ export class AppUsersManager extends AppManager { }); } + public resolveUserByUsername(username: string) { + return callbackify(this.resolveUsername(username), (peer) => { + return peer?._ === 'user' ? peer : undefined; + }); + } + private processResolvedPeer(resolvedPeer: ContactsResolvedPeer.contactsResolvedPeer) { this.saveApiUsers(resolvedPeer.users); this.appChatsManager.saveApiChats(resolvedPeer.chats); diff --git a/src/lib/appManagers/getProxiedManagers.ts b/src/lib/appManagers/getProxiedManagers.ts index b9aebc04..172c1abc 100644 --- a/src/lib/appManagers/getProxiedManagers.ts +++ b/src/lib/appManagers/getProxiedManagers.ts @@ -60,7 +60,9 @@ import DEBUG from '../../config/debug'; // sentMethods2 = {}; // }, 2000); -const DEBUG_MANAGER_REQUESTS: {[managerName: string]: Set} = {}; +const DEBUG_MANAGER_REQUESTS: {[managerName: string]: Set} = { + // appProfileManager: new Set(['getProfile', 'getProfileByPeerId']) +}; if(DEBUG) { (window as any).DEBUG_MANAGER_REQUESTS = DEBUG_MANAGER_REQUESTS; } @@ -84,7 +86,7 @@ function createProxy(/* source: T, */name: string, ack?: boolean) { if(DEBUG) { if(DEBUG_MANAGER_REQUESTS[name]?.has(p as any)) { - console.warn('manager request', name, p, args); + console.warn('manager request', name, p, args, ack); } } diff --git a/src/lib/appManagers/internalLink.ts b/src/lib/appManagers/internalLink.ts index b8a6b49b..270efb23 100644 --- a/src/lib/appManagers/internalLink.ts +++ b/src/lib/appManagers/internalLink.ts @@ -12,10 +12,11 @@ export enum INTERNAL_LINK_TYPE { VOICE_CHAT, USER_PHONE_NUMBER, INVOICE, - EMOJI_SET + EMOJI_SET, + ATTACH_MENU_BOT }; -export type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber | InternalLink.InternalLinkInvoice | InternalLink.InternalLinkEmojiSet; +export type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber | InternalLink.InternalLinkInvoice | InternalLink.InternalLinkEmojiSet | InternalLink.InternalLinkAttachMenuBot; export namespace InternalLink { export interface InternalLinkMessage { @@ -73,6 +74,15 @@ export namespace InternalLink { _: INTERNAL_LINK_TYPE.EMOJI_SET, set: string } + + export interface InternalLinkAttachMenuBot { + _: INTERNAL_LINK_TYPE.ATTACH_MENU_BOT, + startattach?: string, + choose?: string, + attach?: string, + domain?: string, + nestedLink?: InternalLink + } } export type InternalLinkTypeMap = { @@ -83,5 +93,6 @@ export type InternalLinkTypeMap = { [INTERNAL_LINK_TYPE.VOICE_CHAT]: InternalLink.InternalLinkVoiceChat, [INTERNAL_LINK_TYPE.USER_PHONE_NUMBER]: InternalLink.InternalLinkUserPhoneNumber, [INTERNAL_LINK_TYPE.INVOICE]: InternalLink.InternalLinkInvoice, - [INTERNAL_LINK_TYPE.EMOJI_SET]: InternalLink.InternalLinkEmojiSet + [INTERNAL_LINK_TYPE.EMOJI_SET]: InternalLink.InternalLinkEmojiSet, + [INTERNAL_LINK_TYPE.ATTACH_MENU_BOT]: InternalLink.InternalLinkAttachMenuBot }; diff --git a/src/lib/richTextProcessor/wrapRichText.ts b/src/lib/richTextProcessor/wrapRichText.ts index 7f4c3855..6dd9c7c5 100644 --- a/src/lib/richTextProcessor/wrapRichText.ts +++ b/src/lib/richTextProcessor/wrapRichText.ts @@ -38,6 +38,7 @@ import replaceContent from '../../helpers/dom/replaceContent'; import BOM from '../../helpers/string/bom'; import framesCache from '../../helpers/framesCache'; import wrapTelegramUrlToAnchor from './wrapTelegramUrlToAnchor'; +import {IS_FIREFOX} from '../../environment/userAgent'; const resizeObserver = new ResizeObserver((entries) => { for(const entry of entries) { @@ -1311,15 +1312,18 @@ export default function wrapRichText(text: string, options: Partial<{ break; } - // case 'messageEntityLinebreak': { - // if(options.noLinebreaks) { - // insertPart(entity, ' '); - // } else { - // insertPart(entity, '
'); - // } + case 'messageEntityLinebreak': { + if(options.wrappingDraft && IS_FIREFOX) { + element = document.createElement('br'); + } + // if(options.noLinebreaks) { + // insertPart(entity, ' '); + // } else { + // insertPart(entity, '
'); + // } - // break; - // } + break; + } case 'messageEntityUrl': case 'messageEntityTextUrl': {