diff --git a/src/api/gramjs/apiBuilders/common.ts b/src/api/gramjs/apiBuilders/common.ts index 515489124..6ef96a1e0 100644 --- a/src/api/gramjs/apiBuilders/common.ts +++ b/src/api/gramjs/apiBuilders/common.ts @@ -17,6 +17,7 @@ import { } from '../../types'; import { compact } from '../../../util/iteratees'; +import localDb from '../localDb'; import { bytesToDataUri } from './helpers'; import { pathBytesToSvg } from './pathBytesToSvg'; import { buildApiPeerId } from './peers'; @@ -154,6 +155,8 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe let blockUserIds: string[] | undefined; let blockChatIds: string[] | undefined; + const localChats = localDb.chats; + rules.forEach((rule) => { if (rule instanceof GramJs.PrivacyValueAllowAll) { visibility ||= 'everybody'; @@ -170,9 +173,20 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe } else if (rule instanceof GramJs.PrivacyValueDisallowUsers) { blockUserIds = rule.users.map((chatId) => buildApiPeerId(chatId, 'user')); } else if (rule instanceof GramJs.PrivacyValueAllowChatParticipants) { - allowChatIds = rule.chats.map((chatId) => buildApiPeerId(chatId, 'chat')); + // Server allows channel ids here, so we need to check + allowChatIds = rule.chats.map((chatId) => { + const dialogId = buildApiPeerId(chatId, 'chat'); + const channelId = buildApiPeerId(chatId, 'channel'); + if (localChats[dialogId]) return dialogId; + return channelId; + }); } else if (rule instanceof GramJs.PrivacyValueDisallowChatParticipants) { - blockChatIds = rule.chats.map((chatId) => buildApiPeerId(chatId, 'chat')); + blockChatIds = rule.chats.map((chatId) => { + const dialogId = buildApiPeerId(chatId, 'chat'); + const channelId = buildApiPeerId(chatId, 'channel'); + if (localChats[dialogId]) return dialogId; + return channelId; + }); } }); diff --git a/src/api/gramjs/gramjsBuilders/index.ts b/src/api/gramjs/gramjsBuilders/index.ts index 61260ac37..5d77a8cda 100644 --- a/src/api/gramjs/gramjsBuilders/index.ts +++ b/src/api/gramjs/gramjsBuilders/index.ts @@ -31,19 +31,18 @@ import { ApiMessageEntityTypes, } from '../../types'; -import { DEFAULT_STATUS_ICON_ID } from '../../../config'; +import { CHANNEL_ID_LENGTH, DEFAULT_STATUS_ICON_ID } from '../../../config'; import { pick } from '../../../util/iteratees'; import { deserializeBytes } from '../helpers'; import localDb from '../localDb'; -const CHANNEL_ID_MIN_LENGTH = 11; // Example: -1234567890 -const CHANNEL_ID_NEW_FORMAT_MIN_LENGTH = 14; // Example: -1001234567890 +const LEGACY_CHANNEL_ID_MIN_LENGTH = 11; // Example: -1234567890 function checkIfChannelId(id: string) { - if (id.length >= CHANNEL_ID_NEW_FORMAT_MIN_LENGTH) return id.startsWith('-100'); + if (id.length >= CHANNEL_ID_LENGTH) return id.startsWith('-100'); // LEGACY Unprefixed channel id - if (id.length === CHANNEL_ID_MIN_LENGTH && id.startsWith('-4')) return false; - return id.length >= CHANNEL_ID_MIN_LENGTH; + if (id.length === LEGACY_CHANNEL_ID_MIN_LENGTH && id.startsWith('-4')) return false; + return id.length >= LEGACY_CHANNEL_ID_MIN_LENGTH; } export function getEntityTypeById(chatOrUserId: string) { @@ -543,7 +542,7 @@ export function buildMtpPeerId(id: string, type: 'user' | 'chat' | 'channel') { } if (type === 'channel') { - if (id.length === CHANNEL_ID_NEW_FORMAT_MIN_LENGTH) { + if (id.length === CHANNEL_ID_LENGTH) { return BigInt(id.slice(4)); } diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx index 5356eda74..63897d812 100644 --- a/src/components/common/Avatar.tsx +++ b/src/components/common/Avatar.tsx @@ -12,7 +12,7 @@ import { IS_TEST } from '../../config'; import { getChatAvatarHash, getChatTitle, - getUserColorKey, + getPeerColorKey, getUserFullName, getUserStoryHtmlId, isChatWithRepliesBot, @@ -208,7 +208,7 @@ const Avatar: FC = ({ const fullClassName = buildClassName( `Avatar size-${size}`, className, - `color-bg-${getUserColorKey(peer)}`, + `color-bg-${getPeerColorKey(peer)}`, isSavedMessages && 'saved-messages', isDeleted && 'deleted-account', isReplies && 'replies-bot-account', diff --git a/src/components/common/EmbeddedMessage.tsx b/src/components/common/EmbeddedMessage.tsx index 8b8396f82..663c595bc 100644 --- a/src/components/common/EmbeddedMessage.tsx +++ b/src/components/common/EmbeddedMessage.tsx @@ -12,8 +12,8 @@ import { getMessageIsSpoiler, getMessageMediaHash, getMessageRoundVideo, + getPeerColorKey, getSenderTitle, - getUserColorKey, isActionMessage, isMessageTranslatable, } from '../../global/helpers'; @@ -93,7 +93,7 @@ const EmbeddedMessage: FC = ({ className={buildClassName( 'EmbeddedMessage', className, - sender && !noUserColors && `color-${getUserColorKey(sender)}`, + sender && !noUserColors && `color-${getPeerColorKey(sender)}`, )} onClick={message && handleClick} onMouseDown={message && handleMouseDown} diff --git a/src/components/common/EmbeddedStory.tsx b/src/components/common/EmbeddedStory.tsx index 147e6f4df..1c282706d 100644 --- a/src/components/common/EmbeddedStory.tsx +++ b/src/components/common/EmbeddedStory.tsx @@ -6,9 +6,9 @@ import type { ApiChat, ApiTypeStory, ApiUser } from '../../api/types'; import type { ObserveFn } from '../../hooks/useIntersectionObserver'; import { + getPeerColorKey, getSenderTitle, getStoryMediaHash, - getUserColorKey, } from '../../global/helpers'; import buildClassName from '../../util/buildClassName'; import { getPictogramDimensions } from './helpers/mediaDimensions'; @@ -75,7 +75,7 @@ const EmbeddedStory: FC = ({ ref={ref} className={buildClassName( 'EmbeddedMessage', - sender && !noUserColors && `color-${getUserColorKey(sender)}`, + sender && !noUserColors && `color-${getPeerColorKey(sender)}`, )} onClick={handleClick} onMouseDown={handleMouseDown} diff --git a/src/components/common/ProfilePhoto.tsx b/src/components/common/ProfilePhoto.tsx index a5e446c72..53dab0090 100644 --- a/src/components/common/ProfilePhoto.tsx +++ b/src/components/common/ProfilePhoto.tsx @@ -6,7 +6,7 @@ import type { ApiChat, ApiPhoto, ApiUser } from '../../api/types'; import { getChatAvatarHash, getChatTitle, - getUserColorKey, + getPeerColorKey, getUserFullName, getVideoAvatarMediaHash, isChatWithRepliesBot, @@ -139,7 +139,7 @@ const ProfilePhoto: FC = ({ const fullClassName = buildClassName( 'ProfilePhoto', - `color-bg-${getUserColorKey(user || chat)}`, + `color-bg-${getPeerColorKey(user || chat)}`, isSavedMessages && 'saved-messages', isDeleted && 'deleted-account', isRepliesChat && 'replies-bot-account', diff --git a/src/components/middle/ContactGreeting.tsx b/src/components/middle/ContactGreeting.tsx index 32759f8fb..17f7bad22 100644 --- a/src/components/middle/ContactGreeting.tsx +++ b/src/components/middle/ContactGreeting.tsx @@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../global'; import type { ApiSticker, ApiUpdateConnectionStateType } from '../../api/types'; import type { MessageList } from '../../global/types'; -import { getUserIdDividend } from '../../global/helpers'; +import { getPeerIdDividend } from '../../global/helpers'; import { selectChat, selectCurrentMessageList } from '../../global/selectors'; import useLang from '../../hooks/useLang'; @@ -94,7 +94,7 @@ const ContactGreeting: FC = ({ export default memo(withGlobal( (global, { userId }): StateProps => { const { stickers } = global.stickers.greeting; - const dividend = getUserIdDividend(userId) + getUserIdDividend(global.currentUserId!); + const dividend = getPeerIdDividend(userId) + getPeerIdDividend(global.currentUserId!); const sticker = stickers?.length ? stickers[dividend % stickers.length] : undefined; const chat = selectChat(global, userId); if (!chat) { diff --git a/src/components/middle/composer/AttachBotItem.tsx b/src/components/middle/composer/AttachBotItem.tsx index 28b1ac4a2..67f48fdc5 100644 --- a/src/components/middle/composer/AttachBotItem.tsx +++ b/src/components/middle/composer/AttachBotItem.tsx @@ -54,12 +54,18 @@ const AttachBotItem: FC = ({ }); const handleClick = useLastCallback(() => { - callAttachBot({ - bot, - chatId: chatId!, - threadId, - isFromSideMenu: isInSideMenu, - }); + if (isInSideMenu) { + callAttachBot({ + bot, + isFromSideMenu: true, + }); + } else { + callAttachBot({ + bot, + chatId: chatId!, + threadId, + }); + } }); const handleCloseMenu = useLastCallback(() => { diff --git a/src/components/middle/message/Message.tsx b/src/components/middle/message/Message.tsx index aa7e6ea03..483f01e5a 100644 --- a/src/components/middle/message/Message.tsx +++ b/src/components/middle/message/Message.tsx @@ -38,8 +38,8 @@ import { getMessageLocation, getMessageSingleCustomEmoji, getMessageSingleRegularEmoji, + getPeerColorKey, getSenderTitle, - getUserColorKey, hasMessageText, isAnonymousOwnMessage, isChatChannel, @@ -1209,7 +1209,7 @@ const Message: FC = ({ senderTitle = getSenderTitle(lang, senderPeer); if (!asForwarded && !isOwn) { - senderColor = `color-${getUserColorKey(senderPeer)}`; + senderColor = `color-${getPeerColorKey(senderPeer)}`; } } else if (forwardInfo?.hiddenUserName) { senderTitle = forwardInfo.hiddenUserName; diff --git a/src/config.ts b/src/config.ts index ea42d037f..7c8a359fc 100644 --- a/src/config.ts +++ b/src/config.ts @@ -129,6 +129,7 @@ export const DRAFT_DEBOUNCE = 10000; // 10s export const SEND_MESSAGE_ACTION_INTERVAL = 3000; // 3s // 10000s from https://corefork.telegram.org/api/url-authorization#automatic-authorization export const APP_CONFIG_REFETCH_INTERVAL = 10000 * 1000; +export const GENERAL_REFETCH_INTERVAL = 60 * 60 * 1000; // 1h export const EDITABLE_INPUT_ID = 'editable-message-text'; export const EDITABLE_INPUT_MODAL_ID = 'editable-message-text-modal'; @@ -282,6 +283,7 @@ export const API_CHAT_TYPES = ['bots', 'channels', 'chats', 'users'] as const; export const SERVICE_NOTIFICATIONS_USER_ID = '777000'; export const REPLIES_USER_ID = '1271266957'; // TODO For Test connection ID must be equal to 708513 export const RESTRICTED_EMOJI_SET_ID = '7173162320003080'; +export const CHANNEL_ID_LENGTH = 14; // 14 symbols, including -100 prefix export const DEFAULT_GIF_SEARCH_BOT_USERNAME = 'gif'; export const ALL_FOLDER_ID = 0; export const ARCHIVED_FOLDER_ID = 1; diff --git a/src/global/actions/api/bots.ts b/src/global/actions/api/bots.ts index 7d7541eb1..33fae244d 100644 --- a/src/global/actions/api/bots.ts +++ b/src/global/actions/api/bots.ts @@ -6,10 +6,12 @@ import type { RequiredGlobalActions } from '../../index'; import type { ActionReturnType, GlobalState, TabArgs } from '../../types'; import { MAIN_THREAD_ID } from '../../../api/types'; +import { GENERAL_REFETCH_INTERVAL } from '../../../config'; import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { buildCollectionByKey } from '../../../util/iteratees'; import { translate } from '../../../util/langProvider'; import PopupManager from '../../../util/PopupManager'; +import requestActionTimeout from '../../../util/requestActionTimeout'; import { debounce } from '../../../util/schedulers'; import { getServerTime } from '../../../util/serverTime'; import { extractCurrentThemeParams } from '../../../util/themeStyle'; @@ -721,7 +723,12 @@ addActionHandler('markBotTrusted', (global, actions, payload): ActionReturnType addActionHandler('loadAttachBots', async (global, actions, payload): Promise => { const { hash } = payload || {}; - await loadAttachBots(global, hash); + const result = await loadAttachBots(global, hash); + + requestActionTimeout({ + action: 'loadAttachBots', + payload: { hash: result?.hash }, + }, GENERAL_REFETCH_INTERVAL); }); addActionHandler('toggleAttachBot', async (global, actions, payload): Promise => { @@ -737,7 +744,7 @@ addActionHandler('toggleAttachBot', async (global, actions, payload): Promise(global: T, hash?: string) { const result = await callApi('loadAttachBots', { hash }); if (!result) { - return; + return undefined; } global = getGlobal(); @@ -750,16 +757,20 @@ async function loadAttachBots(global: T, hash?: string) { }, }; setGlobal(global); + + return result; } addActionHandler('callAttachBot', (global, actions, payload): ActionReturnType => { const { - chatId, bot, url, startParam, threadId, isFromSideMenu, - tabId = getCurrentTabId(), + bot, startParam, isFromConfirm, tabId = getCurrentTabId(), } = payload; + const isFromSideMenu = 'isFromSideMenu' in payload && payload.isFromSideMenu; + const isFromBotMenu = !bot; - if ((!isFromBotMenu && !global.attachMenu.bots[bot.id]) - || (isFromSideMenu && (bot?.isInactive || bot?.isDisclaimerNeeded))) { + const shouldDisplayDisclaimer = (!isFromBotMenu && !global.attachMenu.bots[bot.id]) + || (isFromSideMenu && (bot?.isInactive || bot?.isDisclaimerNeeded)); + if (!isFromConfirm && shouldDisplayDisclaimer) { return updateTabState(global, { requestedAttachBotInstall: { bot, @@ -767,11 +778,7 @@ addActionHandler('callAttachBot', (global, actions, payload): ActionReturnType = action: 'callAttachBot', payload: { ...payload, - bot: { - ...bot, - isInactive: false, - isDisclaimerNeeded: false, - }, + isFromConfirm: true, }, }, }, @@ -784,15 +791,19 @@ addActionHandler('callAttachBot', (global, actions, payload): ActionReturnType = botId: bot!.id, buttonText: '', isFromSideMenu: true, + startParam, theme, tabId, }); - } else { + } + + if ('chatId' in payload) { + const { chatId, threadId, url } = payload; actions.openChat({ id: chatId, threadId, tabId }); actions.requestWebView({ url, - peerId: chatId, - botId: isFromBotMenu ? chatId : bot.id, + peerId: chatId!, + botId: (isFromBotMenu ? chatId : bot.id)!, theme, buttonText: '', isFromBotMenu, @@ -818,6 +829,7 @@ addActionHandler('confirmAttachBotInstall', async (global, actions, payload): Pr const botUser = selectUser(global, bot.id); if (!botUser) return; + actions.markBotTrusted({ botId: bot.id, isWriteAllowed, tabId }); await callApi('toggleAttachBot', { bot: botUser, isWriteAllowed, isEnabled: true }); if (onConfirm) { const { action, payload: actionPayload } = onConfirm; diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index 555247675..58c0812be 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -999,14 +999,15 @@ addActionHandler('openTelegramLink', (global, actions, payload): ActionReturnTyp hash = part2; } - const startAttach = params.hasOwnProperty('startattach') && !params.startattach ? true : params.startattach; + const hasStartAttach = params.hasOwnProperty('startattach'); + const hasStartApp = params.hasOwnProperty('startapp'); const choose = parseChooseParameter(params.choose); const storyId = part2 === 's' && (Number(part3) || undefined); if (part1.match(/^\+([0-9]+)(\?|$)/)) { openChatByPhoneNumber({ phoneNumber: part1.substr(1, part1.length - 1), - startAttach, + startAttach: params.startattach, attach: params.attach, tabId, }); @@ -1087,11 +1088,11 @@ addActionHandler('openTelegramLink', (global, actions, payload): ActionReturnTyp slug: part2, tabId, }); - } else if (startAttach && choose) { + } else if ((hasStartAttach && choose) || (!part2 && hasStartApp)) { processAttachBotParameters({ username: part1, filter: choose, - ...(typeof startAttach === 'string' && { startParam: startAttach }), + startParam: params.startattach || params.startapp, tabId, }); } else { @@ -1101,7 +1102,7 @@ addActionHandler('openTelegramLink', (global, actions, payload): ActionReturnTyp threadId: messageId ? Number(chatOrChannelPostId) : undefined, commentId, startParam: params.start, - startAttach, + startAttach: params.startattach, attach: params.attach, startApp: params.startapp, originalParts: [part1, part2, part3], @@ -1701,6 +1702,18 @@ addActionHandler('processAttachBotParameters', async (global, actions, payload): const bot = await getAttachBotOrNotify(global, actions, username, tabId); if (!bot) return; + const isForChat = Boolean(filter); + + if (!isForChat) { + actions.callAttachBot({ + isFromSideMenu: true, + bot, + startParam, + tabId, + }); + return; + } + global = getGlobal(); const { attachMenu: { bots } } = global; if (!bots[bot.id]) { @@ -1720,7 +1733,6 @@ addActionHandler('processAttachBotParameters', async (global, actions, payload): setGlobal(global); return; } - actions.requestAttachBotInChat({ bot, filter, diff --git a/src/global/actions/api/reactions.ts b/src/global/actions/api/reactions.ts index 26a0c7cf9..c75fef992 100644 --- a/src/global/actions/api/reactions.ts +++ b/src/global/actions/api/reactions.ts @@ -1,9 +1,11 @@ import type { ActionReturnType } from '../../types'; import { ApiMediaFormat } from '../../../api/types'; +import { GENERAL_REFETCH_INTERVAL } from '../../../config'; import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { buildCollectionByKey, omit } from '../../../util/iteratees'; import * as mediaLoader from '../../../util/mediaLoader'; +import requestActionTimeout from '../../../util/requestActionTimeout'; import { callApi } from '../../../api/gramjs'; import { getDocumentMediaHash, @@ -61,6 +63,11 @@ addActionHandler('loadAvailableReactions', async (global): Promise => { availableReactions: result, }; setGlobal(global); + + requestActionTimeout({ + action: 'loadAvailableReactions', + payload: undefined, + }, GENERAL_REFETCH_INTERVAL); }); addActionHandler('interactWithAnimatedEmoji', (global, actions, payload): ActionReturnType => { diff --git a/src/global/helpers/chats.ts b/src/global/helpers/chats.ts index 50774ca54..8ef0887a8 100644 --- a/src/global/helpers/chats.ts +++ b/src/global/helpers/chats.ts @@ -13,7 +13,7 @@ import { } from '../../api/types'; import { - ARCHIVED_FOLDER_ID, GENERAL_TOPIC_ID, REPLIES_USER_ID, TME_LINK_PREFIX, + ARCHIVED_FOLDER_ID, CHANNEL_ID_LENGTH, GENERAL_TOPIC_ID, REPLIES_USER_ID, TME_LINK_PREFIX, } from '../../config'; import { formatDateToString, formatTime } from '../../util/dateFormat'; import { orderBy } from '../../util/iteratees'; @@ -24,11 +24,16 @@ const FOREVER_BANNED_DATE = Date.now() / 1000 + 31622400; // 366 days const VERIFIED_PRIORITY_BASE = 3e9; const PINNED_PRIORITY_BASE = 3e8; +const USER_COLOR_KEYS = [1, 8, 5, 2, 7, 4, 6]; export function isUserId(entityId: string) { return !entityId.startsWith('-'); } +export function isChannelId(entityId: string) { + return entityId.length === CHANNEL_ID_LENGTH && entityId.startsWith('-100'); +} + export function isChatGroup(chat: ApiChat) { return isChatBasicGroup(chat) || isChatSuperGroup(chat); } @@ -448,3 +453,18 @@ export function getOrderedTopics( return [...pinnedOrdered, ...ordered, ...hidden]; } } + +export function getCleanPeerId(peerId: string) { + return isChannelId(peerId) ? peerId.replace('-100', '') : peerId.replace('-', ''); +} + +export function getPeerIdDividend(peerId: string) { + return Math.abs(Number(getCleanPeerId(peerId))); +} + +// https://github.com/telegramdesktop/tdesktop/blob/371510cfe23b0bd226de8c076bc49248fbe40c26/Telegram/SourceFiles/data/data_peer.cpp#L53 +export function getPeerColorKey(peer: ApiUser | ApiChat | undefined) { + const index = peer ? getPeerIdDividend(peer.id) % 7 : 0; + + return USER_COLOR_KEYS[index]; +} diff --git a/src/global/helpers/users.ts b/src/global/helpers/users.ts index 95bab0605..d847c4d3f 100644 --- a/src/global/helpers/users.ts +++ b/src/global/helpers/users.ts @@ -8,8 +8,6 @@ import { formatPhoneNumber } from '../../util/phoneNumber'; import { prepareSearchWordsForNeedle } from '../../util/searchWords'; import { getServerTime, getServerTimeOffset } from '../../util/serverTime'; -const USER_COLOR_KEYS = [1, 8, 5, 2, 7, 4, 6]; - export function getUserFirstOrLastName(user?: ApiUser) { if (!user) { return undefined; @@ -261,17 +259,6 @@ export function filterUsersByName( }); } -export function getUserIdDividend(peerId: string) { - return Math.abs(Number(peerId)); -} - -// https://github.com/telegramdesktop/tdesktop/blob/371510cfe23b0bd226de8c076bc49248fbe40c26/Telegram/SourceFiles/data/data_peer.cpp#L53 -export function getUserColorKey(peer: ApiUser | ApiChat | undefined) { - const index = peer ? getUserIdDividend(peer.id) % 7 : 0; - - return USER_COLOR_KEYS[index]; -} - export function getMainUsername(userOrChat: ApiUser | ApiChat) { return userOrChat.usernames?.find((u) => u.isActive)?.username; } diff --git a/src/global/types.ts b/src/global/types.ts index 48a4ba44e..6ac44d9aa 100644 --- a/src/global/types.ts +++ b/src/global/types.ts @@ -2378,7 +2378,7 @@ export interface ActionPayloads { processAttachBotParameters: { username: string; - filter: ApiChatType[]; + filter?: ApiChatType[]; startParam?: string; } & WithTabId; requestAttachBotInChat: { @@ -2404,13 +2404,16 @@ export interface ActionPayloads { isEnabled: boolean; }; - callAttachBot: { + callAttachBot: ({ chatId: string; threadId?: number; - bot?: ApiAttachBot; url?: string; + } | { + isFromSideMenu: true; + }) & { startParam?: string; - isFromSideMenu?: boolean; + bot?: ApiAttachBot; + isFromConfirm?: boolean; } & WithTabId; requestBotUrlAuth: { diff --git a/src/util/deeplink.ts b/src/util/deeplink.ts index 59f3dbd34..bbf37a3dd 100644 --- a/src/util/deeplink.ts +++ b/src/util/deeplink.ts @@ -41,7 +41,8 @@ export const processDeepLink = (url: string) => { appname, startapp, story, } = params; - const startAttach = params.hasOwnProperty('startattach') && !startattach ? true : startattach; + const hasStartAttach = params.hasOwnProperty('startattach'); + const hasStartApp = params.hasOwnProperty('startapp'); const choose = parseChooseParameter(params.choose); const threadId = Number(thread) || Number(topic) || undefined; @@ -52,11 +53,11 @@ export const processDeepLink = (url: string) => { startApp: startapp, originalParts: [domain, appname], }); - } else if (startAttach && choose) { + } else if ((hasStartAttach && choose) || (!appname && hasStartApp)) { processAttachBotParameters({ username: domain, filter: choose, - ...(typeof startAttach === 'string' && { startParam: startAttach }), + startParam: startattach || startapp, }); } else if (params.hasOwnProperty('voicechat') || params.hasOwnProperty('livestream')) { joinVoiceChatByLink({ @@ -64,7 +65,7 @@ export const processDeepLink = (url: string) => { inviteHash: voicechat || livestream, }); } else if (phone) { - openChatByPhoneNumber({ phoneNumber: phone, startAttach, attach }); + openChatByPhoneNumber({ phoneNumber: phone, startAttach: startattach, attach }); } else if (story) { openStoryViewerByUsername({ username: domain, storyId: Number(story) }); } else { @@ -73,7 +74,7 @@ export const processDeepLink = (url: string) => { messageId: post ? Number(post) : undefined, commentId: comment ? Number(comment) : undefined, startParam: start, - startAttach, + startAttach: startattach, attach, threadId, }); diff --git a/src/util/requestActionTimeout.ts b/src/util/requestActionTimeout.ts index b3d8d3e08..e22b1f727 100644 --- a/src/util/requestActionTimeout.ts +++ b/src/util/requestActionTimeout.ts @@ -4,6 +4,7 @@ import type { CallbackAction } from '../global/types'; const callbacks = new Map(); +// TODO Pass callbacks to the master tab. Sync them on master change export default function requestActionTimeout(action: CallbackAction, timeout: number) { const name = action.action; clearTimeout(callbacks.get(name));