Chats: Various fixes (#3880)
This commit is contained in:
parent
e8c4b8f713
commit
b89ef33aec
@ -17,6 +17,7 @@ import {
|
|||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import { compact } from '../../../util/iteratees';
|
import { compact } from '../../../util/iteratees';
|
||||||
|
import localDb from '../localDb';
|
||||||
import { bytesToDataUri } from './helpers';
|
import { bytesToDataUri } from './helpers';
|
||||||
import { pathBytesToSvg } from './pathBytesToSvg';
|
import { pathBytesToSvg } from './pathBytesToSvg';
|
||||||
import { buildApiPeerId } from './peers';
|
import { buildApiPeerId } from './peers';
|
||||||
@ -154,6 +155,8 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
|
|||||||
let blockUserIds: string[] | undefined;
|
let blockUserIds: string[] | undefined;
|
||||||
let blockChatIds: string[] | undefined;
|
let blockChatIds: string[] | undefined;
|
||||||
|
|
||||||
|
const localChats = localDb.chats;
|
||||||
|
|
||||||
rules.forEach((rule) => {
|
rules.forEach((rule) => {
|
||||||
if (rule instanceof GramJs.PrivacyValueAllowAll) {
|
if (rule instanceof GramJs.PrivacyValueAllowAll) {
|
||||||
visibility ||= 'everybody';
|
visibility ||= 'everybody';
|
||||||
@ -170,9 +173,20 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
|
|||||||
} else if (rule instanceof GramJs.PrivacyValueDisallowUsers) {
|
} else if (rule instanceof GramJs.PrivacyValueDisallowUsers) {
|
||||||
blockUserIds = rule.users.map((chatId) => buildApiPeerId(chatId, 'user'));
|
blockUserIds = rule.users.map((chatId) => buildApiPeerId(chatId, 'user'));
|
||||||
} else if (rule instanceof GramJs.PrivacyValueAllowChatParticipants) {
|
} 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) {
|
} 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;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -31,19 +31,18 @@ import {
|
|||||||
ApiMessageEntityTypes,
|
ApiMessageEntityTypes,
|
||||||
} from '../../types';
|
} 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 { pick } from '../../../util/iteratees';
|
||||||
import { deserializeBytes } from '../helpers';
|
import { deserializeBytes } from '../helpers';
|
||||||
import localDb from '../localDb';
|
import localDb from '../localDb';
|
||||||
|
|
||||||
const CHANNEL_ID_MIN_LENGTH = 11; // Example: -1234567890
|
const LEGACY_CHANNEL_ID_MIN_LENGTH = 11; // Example: -1234567890
|
||||||
const CHANNEL_ID_NEW_FORMAT_MIN_LENGTH = 14; // Example: -1001234567890
|
|
||||||
|
|
||||||
function checkIfChannelId(id: string) {
|
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
|
// LEGACY Unprefixed channel id
|
||||||
if (id.length === CHANNEL_ID_MIN_LENGTH && id.startsWith('-4')) return false;
|
if (id.length === LEGACY_CHANNEL_ID_MIN_LENGTH && id.startsWith('-4')) return false;
|
||||||
return id.length >= CHANNEL_ID_MIN_LENGTH;
|
return id.length >= LEGACY_CHANNEL_ID_MIN_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEntityTypeById(chatOrUserId: string) {
|
export function getEntityTypeById(chatOrUserId: string) {
|
||||||
@ -543,7 +542,7 @@ export function buildMtpPeerId(id: string, type: 'user' | 'chat' | 'channel') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'channel') {
|
if (type === 'channel') {
|
||||||
if (id.length === CHANNEL_ID_NEW_FORMAT_MIN_LENGTH) {
|
if (id.length === CHANNEL_ID_LENGTH) {
|
||||||
return BigInt(id.slice(4));
|
return BigInt(id.slice(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { IS_TEST } from '../../config';
|
|||||||
import {
|
import {
|
||||||
getChatAvatarHash,
|
getChatAvatarHash,
|
||||||
getChatTitle,
|
getChatTitle,
|
||||||
getUserColorKey,
|
getPeerColorKey,
|
||||||
getUserFullName,
|
getUserFullName,
|
||||||
getUserStoryHtmlId,
|
getUserStoryHtmlId,
|
||||||
isChatWithRepliesBot,
|
isChatWithRepliesBot,
|
||||||
@ -208,7 +208,7 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
const fullClassName = buildClassName(
|
const fullClassName = buildClassName(
|
||||||
`Avatar size-${size}`,
|
`Avatar size-${size}`,
|
||||||
className,
|
className,
|
||||||
`color-bg-${getUserColorKey(peer)}`,
|
`color-bg-${getPeerColorKey(peer)}`,
|
||||||
isSavedMessages && 'saved-messages',
|
isSavedMessages && 'saved-messages',
|
||||||
isDeleted && 'deleted-account',
|
isDeleted && 'deleted-account',
|
||||||
isReplies && 'replies-bot-account',
|
isReplies && 'replies-bot-account',
|
||||||
|
|||||||
@ -12,8 +12,8 @@ import {
|
|||||||
getMessageIsSpoiler,
|
getMessageIsSpoiler,
|
||||||
getMessageMediaHash,
|
getMessageMediaHash,
|
||||||
getMessageRoundVideo,
|
getMessageRoundVideo,
|
||||||
|
getPeerColorKey,
|
||||||
getSenderTitle,
|
getSenderTitle,
|
||||||
getUserColorKey,
|
|
||||||
isActionMessage,
|
isActionMessage,
|
||||||
isMessageTranslatable,
|
isMessageTranslatable,
|
||||||
} from '../../global/helpers';
|
} from '../../global/helpers';
|
||||||
@ -93,7 +93,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
|||||||
className={buildClassName(
|
className={buildClassName(
|
||||||
'EmbeddedMessage',
|
'EmbeddedMessage',
|
||||||
className,
|
className,
|
||||||
sender && !noUserColors && `color-${getUserColorKey(sender)}`,
|
sender && !noUserColors && `color-${getPeerColorKey(sender)}`,
|
||||||
)}
|
)}
|
||||||
onClick={message && handleClick}
|
onClick={message && handleClick}
|
||||||
onMouseDown={message && handleMouseDown}
|
onMouseDown={message && handleMouseDown}
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import type { ApiChat, ApiTypeStory, ApiUser } from '../../api/types';
|
|||||||
import type { ObserveFn } from '../../hooks/useIntersectionObserver';
|
import type { ObserveFn } from '../../hooks/useIntersectionObserver';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
getPeerColorKey,
|
||||||
getSenderTitle,
|
getSenderTitle,
|
||||||
getStoryMediaHash,
|
getStoryMediaHash,
|
||||||
getUserColorKey,
|
|
||||||
} from '../../global/helpers';
|
} from '../../global/helpers';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { getPictogramDimensions } from './helpers/mediaDimensions';
|
import { getPictogramDimensions } from './helpers/mediaDimensions';
|
||||||
@ -75,7 +75,7 @@ const EmbeddedStory: FC<OwnProps> = ({
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
className={buildClassName(
|
className={buildClassName(
|
||||||
'EmbeddedMessage',
|
'EmbeddedMessage',
|
||||||
sender && !noUserColors && `color-${getUserColorKey(sender)}`,
|
sender && !noUserColors && `color-${getPeerColorKey(sender)}`,
|
||||||
)}
|
)}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
onMouseDown={handleMouseDown}
|
onMouseDown={handleMouseDown}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import type { ApiChat, ApiPhoto, ApiUser } from '../../api/types';
|
|||||||
import {
|
import {
|
||||||
getChatAvatarHash,
|
getChatAvatarHash,
|
||||||
getChatTitle,
|
getChatTitle,
|
||||||
getUserColorKey,
|
getPeerColorKey,
|
||||||
getUserFullName,
|
getUserFullName,
|
||||||
getVideoAvatarMediaHash,
|
getVideoAvatarMediaHash,
|
||||||
isChatWithRepliesBot,
|
isChatWithRepliesBot,
|
||||||
@ -139,7 +139,7 @@ const ProfilePhoto: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const fullClassName = buildClassName(
|
const fullClassName = buildClassName(
|
||||||
'ProfilePhoto',
|
'ProfilePhoto',
|
||||||
`color-bg-${getUserColorKey(user || chat)}`,
|
`color-bg-${getPeerColorKey(user || chat)}`,
|
||||||
isSavedMessages && 'saved-messages',
|
isSavedMessages && 'saved-messages',
|
||||||
isDeleted && 'deleted-account',
|
isDeleted && 'deleted-account',
|
||||||
isRepliesChat && 'replies-bot-account',
|
isRepliesChat && 'replies-bot-account',
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../global';
|
|||||||
import type { ApiSticker, ApiUpdateConnectionStateType } from '../../api/types';
|
import type { ApiSticker, ApiUpdateConnectionStateType } from '../../api/types';
|
||||||
import type { MessageList } from '../../global/types';
|
import type { MessageList } from '../../global/types';
|
||||||
|
|
||||||
import { getUserIdDividend } from '../../global/helpers';
|
import { getPeerIdDividend } from '../../global/helpers';
|
||||||
import { selectChat, selectCurrentMessageList } from '../../global/selectors';
|
import { selectChat, selectCurrentMessageList } from '../../global/selectors';
|
||||||
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -94,7 +94,7 @@ const ContactGreeting: FC<OwnProps & StateProps> = ({
|
|||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
(global, { userId }): StateProps => {
|
(global, { userId }): StateProps => {
|
||||||
const { stickers } = global.stickers.greeting;
|
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 sticker = stickers?.length ? stickers[dividend % stickers.length] : undefined;
|
||||||
const chat = selectChat(global, userId);
|
const chat = selectChat(global, userId);
|
||||||
if (!chat) {
|
if (!chat) {
|
||||||
|
|||||||
@ -54,12 +54,18 @@ const AttachBotItem: FC<OwnProps> = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleClick = useLastCallback(() => {
|
const handleClick = useLastCallback(() => {
|
||||||
callAttachBot({
|
if (isInSideMenu) {
|
||||||
bot,
|
callAttachBot({
|
||||||
chatId: chatId!,
|
bot,
|
||||||
threadId,
|
isFromSideMenu: true,
|
||||||
isFromSideMenu: isInSideMenu,
|
});
|
||||||
});
|
} else {
|
||||||
|
callAttachBot({
|
||||||
|
bot,
|
||||||
|
chatId: chatId!,
|
||||||
|
threadId,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCloseMenu = useLastCallback(() => {
|
const handleCloseMenu = useLastCallback(() => {
|
||||||
|
|||||||
@ -38,8 +38,8 @@ import {
|
|||||||
getMessageLocation,
|
getMessageLocation,
|
||||||
getMessageSingleCustomEmoji,
|
getMessageSingleCustomEmoji,
|
||||||
getMessageSingleRegularEmoji,
|
getMessageSingleRegularEmoji,
|
||||||
|
getPeerColorKey,
|
||||||
getSenderTitle,
|
getSenderTitle,
|
||||||
getUserColorKey,
|
|
||||||
hasMessageText,
|
hasMessageText,
|
||||||
isAnonymousOwnMessage,
|
isAnonymousOwnMessage,
|
||||||
isChatChannel,
|
isChatChannel,
|
||||||
@ -1209,7 +1209,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
senderTitle = getSenderTitle(lang, senderPeer);
|
senderTitle = getSenderTitle(lang, senderPeer);
|
||||||
|
|
||||||
if (!asForwarded && !isOwn) {
|
if (!asForwarded && !isOwn) {
|
||||||
senderColor = `color-${getUserColorKey(senderPeer)}`;
|
senderColor = `color-${getPeerColorKey(senderPeer)}`;
|
||||||
}
|
}
|
||||||
} else if (forwardInfo?.hiddenUserName) {
|
} else if (forwardInfo?.hiddenUserName) {
|
||||||
senderTitle = forwardInfo.hiddenUserName;
|
senderTitle = forwardInfo.hiddenUserName;
|
||||||
|
|||||||
@ -129,6 +129,7 @@ export const DRAFT_DEBOUNCE = 10000; // 10s
|
|||||||
export const SEND_MESSAGE_ACTION_INTERVAL = 3000; // 3s
|
export const SEND_MESSAGE_ACTION_INTERVAL = 3000; // 3s
|
||||||
// 10000s from https://corefork.telegram.org/api/url-authorization#automatic-authorization
|
// 10000s from https://corefork.telegram.org/api/url-authorization#automatic-authorization
|
||||||
export const APP_CONFIG_REFETCH_INTERVAL = 10000 * 1000;
|
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_ID = 'editable-message-text';
|
||||||
export const EDITABLE_INPUT_MODAL_ID = 'editable-message-text-modal';
|
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 SERVICE_NOTIFICATIONS_USER_ID = '777000';
|
||||||
export const REPLIES_USER_ID = '1271266957'; // TODO For Test connection ID must be equal to 708513
|
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 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 DEFAULT_GIF_SEARCH_BOT_USERNAME = 'gif';
|
||||||
export const ALL_FOLDER_ID = 0;
|
export const ALL_FOLDER_ID = 0;
|
||||||
export const ARCHIVED_FOLDER_ID = 1;
|
export const ARCHIVED_FOLDER_ID = 1;
|
||||||
|
|||||||
@ -6,10 +6,12 @@ import type { RequiredGlobalActions } from '../../index';
|
|||||||
import type { ActionReturnType, GlobalState, TabArgs } from '../../types';
|
import type { ActionReturnType, GlobalState, TabArgs } from '../../types';
|
||||||
import { MAIN_THREAD_ID } from '../../../api/types';
|
import { MAIN_THREAD_ID } from '../../../api/types';
|
||||||
|
|
||||||
|
import { GENERAL_REFETCH_INTERVAL } from '../../../config';
|
||||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||||
import { translate } from '../../../util/langProvider';
|
import { translate } from '../../../util/langProvider';
|
||||||
import PopupManager from '../../../util/PopupManager';
|
import PopupManager from '../../../util/PopupManager';
|
||||||
|
import requestActionTimeout from '../../../util/requestActionTimeout';
|
||||||
import { debounce } from '../../../util/schedulers';
|
import { debounce } from '../../../util/schedulers';
|
||||||
import { getServerTime } from '../../../util/serverTime';
|
import { getServerTime } from '../../../util/serverTime';
|
||||||
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||||
@ -721,7 +723,12 @@ addActionHandler('markBotTrusted', (global, actions, payload): ActionReturnType
|
|||||||
|
|
||||||
addActionHandler('loadAttachBots', async (global, actions, payload): Promise<void> => {
|
addActionHandler('loadAttachBots', async (global, actions, payload): Promise<void> => {
|
||||||
const { hash } = payload || {};
|
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<void> => {
|
addActionHandler('toggleAttachBot', async (global, actions, payload): Promise<void> => {
|
||||||
@ -737,7 +744,7 @@ addActionHandler('toggleAttachBot', async (global, actions, payload): Promise<vo
|
|||||||
async function loadAttachBots<T extends GlobalState>(global: T, hash?: string) {
|
async function loadAttachBots<T extends GlobalState>(global: T, hash?: string) {
|
||||||
const result = await callApi('loadAttachBots', { hash });
|
const result = await callApi('loadAttachBots', { hash });
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
global = getGlobal();
|
global = getGlobal();
|
||||||
@ -750,16 +757,20 @@ async function loadAttachBots<T extends GlobalState>(global: T, hash?: string) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
addActionHandler('callAttachBot', (global, actions, payload): ActionReturnType => {
|
addActionHandler('callAttachBot', (global, actions, payload): ActionReturnType => {
|
||||||
const {
|
const {
|
||||||
chatId, bot, url, startParam, threadId, isFromSideMenu,
|
bot, startParam, isFromConfirm, tabId = getCurrentTabId(),
|
||||||
tabId = getCurrentTabId(),
|
|
||||||
} = payload;
|
} = payload;
|
||||||
|
const isFromSideMenu = 'isFromSideMenu' in payload && payload.isFromSideMenu;
|
||||||
|
|
||||||
const isFromBotMenu = !bot;
|
const isFromBotMenu = !bot;
|
||||||
if ((!isFromBotMenu && !global.attachMenu.bots[bot.id])
|
const shouldDisplayDisclaimer = (!isFromBotMenu && !global.attachMenu.bots[bot.id])
|
||||||
|| (isFromSideMenu && (bot?.isInactive || bot?.isDisclaimerNeeded))) {
|
|| (isFromSideMenu && (bot?.isInactive || bot?.isDisclaimerNeeded));
|
||||||
|
if (!isFromConfirm && shouldDisplayDisclaimer) {
|
||||||
return updateTabState(global, {
|
return updateTabState(global, {
|
||||||
requestedAttachBotInstall: {
|
requestedAttachBotInstall: {
|
||||||
bot,
|
bot,
|
||||||
@ -767,11 +778,7 @@ addActionHandler('callAttachBot', (global, actions, payload): ActionReturnType =
|
|||||||
action: 'callAttachBot',
|
action: 'callAttachBot',
|
||||||
payload: {
|
payload: {
|
||||||
...payload,
|
...payload,
|
||||||
bot: {
|
isFromConfirm: true,
|
||||||
...bot,
|
|
||||||
isInactive: false,
|
|
||||||
isDisclaimerNeeded: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -784,15 +791,19 @@ addActionHandler('callAttachBot', (global, actions, payload): ActionReturnType =
|
|||||||
botId: bot!.id,
|
botId: bot!.id,
|
||||||
buttonText: '',
|
buttonText: '',
|
||||||
isFromSideMenu: true,
|
isFromSideMenu: true,
|
||||||
|
startParam,
|
||||||
theme,
|
theme,
|
||||||
tabId,
|
tabId,
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if ('chatId' in payload) {
|
||||||
|
const { chatId, threadId, url } = payload;
|
||||||
actions.openChat({ id: chatId, threadId, tabId });
|
actions.openChat({ id: chatId, threadId, tabId });
|
||||||
actions.requestWebView({
|
actions.requestWebView({
|
||||||
url,
|
url,
|
||||||
peerId: chatId,
|
peerId: chatId!,
|
||||||
botId: isFromBotMenu ? chatId : bot.id,
|
botId: (isFromBotMenu ? chatId : bot.id)!,
|
||||||
theme,
|
theme,
|
||||||
buttonText: '',
|
buttonText: '',
|
||||||
isFromBotMenu,
|
isFromBotMenu,
|
||||||
@ -818,6 +829,7 @@ addActionHandler('confirmAttachBotInstall', async (global, actions, payload): Pr
|
|||||||
const botUser = selectUser(global, bot.id);
|
const botUser = selectUser(global, bot.id);
|
||||||
if (!botUser) return;
|
if (!botUser) return;
|
||||||
|
|
||||||
|
actions.markBotTrusted({ botId: bot.id, isWriteAllowed, tabId });
|
||||||
await callApi('toggleAttachBot', { bot: botUser, isWriteAllowed, isEnabled: true });
|
await callApi('toggleAttachBot', { bot: botUser, isWriteAllowed, isEnabled: true });
|
||||||
if (onConfirm) {
|
if (onConfirm) {
|
||||||
const { action, payload: actionPayload } = onConfirm;
|
const { action, payload: actionPayload } = onConfirm;
|
||||||
|
|||||||
@ -999,14 +999,15 @@ addActionHandler('openTelegramLink', (global, actions, payload): ActionReturnTyp
|
|||||||
hash = part2;
|
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 choose = parseChooseParameter(params.choose);
|
||||||
const storyId = part2 === 's' && (Number(part3) || undefined);
|
const storyId = part2 === 's' && (Number(part3) || undefined);
|
||||||
|
|
||||||
if (part1.match(/^\+([0-9]+)(\?|$)/)) {
|
if (part1.match(/^\+([0-9]+)(\?|$)/)) {
|
||||||
openChatByPhoneNumber({
|
openChatByPhoneNumber({
|
||||||
phoneNumber: part1.substr(1, part1.length - 1),
|
phoneNumber: part1.substr(1, part1.length - 1),
|
||||||
startAttach,
|
startAttach: params.startattach,
|
||||||
attach: params.attach,
|
attach: params.attach,
|
||||||
tabId,
|
tabId,
|
||||||
});
|
});
|
||||||
@ -1087,11 +1088,11 @@ addActionHandler('openTelegramLink', (global, actions, payload): ActionReturnTyp
|
|||||||
slug: part2,
|
slug: part2,
|
||||||
tabId,
|
tabId,
|
||||||
});
|
});
|
||||||
} else if (startAttach && choose) {
|
} else if ((hasStartAttach && choose) || (!part2 && hasStartApp)) {
|
||||||
processAttachBotParameters({
|
processAttachBotParameters({
|
||||||
username: part1,
|
username: part1,
|
||||||
filter: choose,
|
filter: choose,
|
||||||
...(typeof startAttach === 'string' && { startParam: startAttach }),
|
startParam: params.startattach || params.startapp,
|
||||||
tabId,
|
tabId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -1101,7 +1102,7 @@ addActionHandler('openTelegramLink', (global, actions, payload): ActionReturnTyp
|
|||||||
threadId: messageId ? Number(chatOrChannelPostId) : undefined,
|
threadId: messageId ? Number(chatOrChannelPostId) : undefined,
|
||||||
commentId,
|
commentId,
|
||||||
startParam: params.start,
|
startParam: params.start,
|
||||||
startAttach,
|
startAttach: params.startattach,
|
||||||
attach: params.attach,
|
attach: params.attach,
|
||||||
startApp: params.startapp,
|
startApp: params.startapp,
|
||||||
originalParts: [part1, part2, part3],
|
originalParts: [part1, part2, part3],
|
||||||
@ -1701,6 +1702,18 @@ addActionHandler('processAttachBotParameters', async (global, actions, payload):
|
|||||||
const bot = await getAttachBotOrNotify(global, actions, username, tabId);
|
const bot = await getAttachBotOrNotify(global, actions, username, tabId);
|
||||||
if (!bot) return;
|
if (!bot) return;
|
||||||
|
|
||||||
|
const isForChat = Boolean(filter);
|
||||||
|
|
||||||
|
if (!isForChat) {
|
||||||
|
actions.callAttachBot({
|
||||||
|
isFromSideMenu: true,
|
||||||
|
bot,
|
||||||
|
startParam,
|
||||||
|
tabId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
global = getGlobal();
|
global = getGlobal();
|
||||||
const { attachMenu: { bots } } = global;
|
const { attachMenu: { bots } } = global;
|
||||||
if (!bots[bot.id]) {
|
if (!bots[bot.id]) {
|
||||||
@ -1720,7 +1733,6 @@ addActionHandler('processAttachBotParameters', async (global, actions, payload):
|
|||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.requestAttachBotInChat({
|
actions.requestAttachBotInChat({
|
||||||
bot,
|
bot,
|
||||||
filter,
|
filter,
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import type { ActionReturnType } from '../../types';
|
import type { ActionReturnType } from '../../types';
|
||||||
import { ApiMediaFormat } from '../../../api/types';
|
import { ApiMediaFormat } from '../../../api/types';
|
||||||
|
|
||||||
|
import { GENERAL_REFETCH_INTERVAL } from '../../../config';
|
||||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
||||||
import * as mediaLoader from '../../../util/mediaLoader';
|
import * as mediaLoader from '../../../util/mediaLoader';
|
||||||
|
import requestActionTimeout from '../../../util/requestActionTimeout';
|
||||||
import { callApi } from '../../../api/gramjs';
|
import { callApi } from '../../../api/gramjs';
|
||||||
import {
|
import {
|
||||||
getDocumentMediaHash,
|
getDocumentMediaHash,
|
||||||
@ -61,6 +63,11 @@ addActionHandler('loadAvailableReactions', async (global): Promise<void> => {
|
|||||||
availableReactions: result,
|
availableReactions: result,
|
||||||
};
|
};
|
||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
|
|
||||||
|
requestActionTimeout({
|
||||||
|
action: 'loadAvailableReactions',
|
||||||
|
payload: undefined,
|
||||||
|
}, GENERAL_REFETCH_INTERVAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('interactWithAnimatedEmoji', (global, actions, payload): ActionReturnType => {
|
addActionHandler('interactWithAnimatedEmoji', (global, actions, payload): ActionReturnType => {
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import {
|
|||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
|
|
||||||
import {
|
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';
|
} from '../../config';
|
||||||
import { formatDateToString, formatTime } from '../../util/dateFormat';
|
import { formatDateToString, formatTime } from '../../util/dateFormat';
|
||||||
import { orderBy } from '../../util/iteratees';
|
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 VERIFIED_PRIORITY_BASE = 3e9;
|
||||||
const PINNED_PRIORITY_BASE = 3e8;
|
const PINNED_PRIORITY_BASE = 3e8;
|
||||||
|
const USER_COLOR_KEYS = [1, 8, 5, 2, 7, 4, 6];
|
||||||
|
|
||||||
export function isUserId(entityId: string) {
|
export function isUserId(entityId: string) {
|
||||||
return !entityId.startsWith('-');
|
return !entityId.startsWith('-');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isChannelId(entityId: string) {
|
||||||
|
return entityId.length === CHANNEL_ID_LENGTH && entityId.startsWith('-100');
|
||||||
|
}
|
||||||
|
|
||||||
export function isChatGroup(chat: ApiChat) {
|
export function isChatGroup(chat: ApiChat) {
|
||||||
return isChatBasicGroup(chat) || isChatSuperGroup(chat);
|
return isChatBasicGroup(chat) || isChatSuperGroup(chat);
|
||||||
}
|
}
|
||||||
@ -448,3 +453,18 @@ export function getOrderedTopics(
|
|||||||
return [...pinnedOrdered, ...ordered, ...hidden];
|
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];
|
||||||
|
}
|
||||||
|
|||||||
@ -8,8 +8,6 @@ import { formatPhoneNumber } from '../../util/phoneNumber';
|
|||||||
import { prepareSearchWordsForNeedle } from '../../util/searchWords';
|
import { prepareSearchWordsForNeedle } from '../../util/searchWords';
|
||||||
import { getServerTime, getServerTimeOffset } from '../../util/serverTime';
|
import { getServerTime, getServerTimeOffset } from '../../util/serverTime';
|
||||||
|
|
||||||
const USER_COLOR_KEYS = [1, 8, 5, 2, 7, 4, 6];
|
|
||||||
|
|
||||||
export function getUserFirstOrLastName(user?: ApiUser) {
|
export function getUserFirstOrLastName(user?: ApiUser) {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return undefined;
|
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) {
|
export function getMainUsername(userOrChat: ApiUser | ApiChat) {
|
||||||
return userOrChat.usernames?.find((u) => u.isActive)?.username;
|
return userOrChat.usernames?.find((u) => u.isActive)?.username;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2378,7 +2378,7 @@ export interface ActionPayloads {
|
|||||||
|
|
||||||
processAttachBotParameters: {
|
processAttachBotParameters: {
|
||||||
username: string;
|
username: string;
|
||||||
filter: ApiChatType[];
|
filter?: ApiChatType[];
|
||||||
startParam?: string;
|
startParam?: string;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
requestAttachBotInChat: {
|
requestAttachBotInChat: {
|
||||||
@ -2404,13 +2404,16 @@ export interface ActionPayloads {
|
|||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
callAttachBot: {
|
callAttachBot: ({
|
||||||
chatId: string;
|
chatId: string;
|
||||||
threadId?: number;
|
threadId?: number;
|
||||||
bot?: ApiAttachBot;
|
|
||||||
url?: string;
|
url?: string;
|
||||||
|
} | {
|
||||||
|
isFromSideMenu: true;
|
||||||
|
}) & {
|
||||||
startParam?: string;
|
startParam?: string;
|
||||||
isFromSideMenu?: boolean;
|
bot?: ApiAttachBot;
|
||||||
|
isFromConfirm?: boolean;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
|
|
||||||
requestBotUrlAuth: {
|
requestBotUrlAuth: {
|
||||||
|
|||||||
@ -41,7 +41,8 @@ export const processDeepLink = (url: string) => {
|
|||||||
appname, startapp, story,
|
appname, startapp, story,
|
||||||
} = params;
|
} = 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 choose = parseChooseParameter(params.choose);
|
||||||
const threadId = Number(thread) || Number(topic) || undefined;
|
const threadId = Number(thread) || Number(topic) || undefined;
|
||||||
|
|
||||||
@ -52,11 +53,11 @@ export const processDeepLink = (url: string) => {
|
|||||||
startApp: startapp,
|
startApp: startapp,
|
||||||
originalParts: [domain, appname],
|
originalParts: [domain, appname],
|
||||||
});
|
});
|
||||||
} else if (startAttach && choose) {
|
} else if ((hasStartAttach && choose) || (!appname && hasStartApp)) {
|
||||||
processAttachBotParameters({
|
processAttachBotParameters({
|
||||||
username: domain,
|
username: domain,
|
||||||
filter: choose,
|
filter: choose,
|
||||||
...(typeof startAttach === 'string' && { startParam: startAttach }),
|
startParam: startattach || startapp,
|
||||||
});
|
});
|
||||||
} else if (params.hasOwnProperty('voicechat') || params.hasOwnProperty('livestream')) {
|
} else if (params.hasOwnProperty('voicechat') || params.hasOwnProperty('livestream')) {
|
||||||
joinVoiceChatByLink({
|
joinVoiceChatByLink({
|
||||||
@ -64,7 +65,7 @@ export const processDeepLink = (url: string) => {
|
|||||||
inviteHash: voicechat || livestream,
|
inviteHash: voicechat || livestream,
|
||||||
});
|
});
|
||||||
} else if (phone) {
|
} else if (phone) {
|
||||||
openChatByPhoneNumber({ phoneNumber: phone, startAttach, attach });
|
openChatByPhoneNumber({ phoneNumber: phone, startAttach: startattach, attach });
|
||||||
} else if (story) {
|
} else if (story) {
|
||||||
openStoryViewerByUsername({ username: domain, storyId: Number(story) });
|
openStoryViewerByUsername({ username: domain, storyId: Number(story) });
|
||||||
} else {
|
} else {
|
||||||
@ -73,7 +74,7 @@ export const processDeepLink = (url: string) => {
|
|||||||
messageId: post ? Number(post) : undefined,
|
messageId: post ? Number(post) : undefined,
|
||||||
commentId: comment ? Number(comment) : undefined,
|
commentId: comment ? Number(comment) : undefined,
|
||||||
startParam: start,
|
startParam: start,
|
||||||
startAttach,
|
startAttach: startattach,
|
||||||
attach,
|
attach,
|
||||||
threadId,
|
threadId,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import type { CallbackAction } from '../global/types';
|
|||||||
|
|
||||||
const callbacks = new Map<string, number>();
|
const callbacks = new Map<string, number>();
|
||||||
|
|
||||||
|
// TODO Pass callbacks to the master tab. Sync them on master change
|
||||||
export default function requestActionTimeout(action: CallbackAction, timeout: number) {
|
export default function requestActionTimeout(action: CallbackAction, timeout: number) {
|
||||||
const name = action.action;
|
const name = action.action;
|
||||||
clearTimeout(callbacks.get(name));
|
clearTimeout(callbacks.get(name));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user