Payment: Support closing form by event from t.me (#1983)

This commit is contained in:
Alexander Zinchuk 2022-08-05 19:23:25 +02:00
parent afd0a00730
commit 0b3db96ea2
11 changed files with 64 additions and 19 deletions

View File

@ -1206,11 +1206,11 @@ function preparePeers(
) {
const store: Record<string, GramJs.TypeChat | GramJs.TypeUser> = {};
result.chats.forEach((chat) => {
result.chats?.forEach((chat) => {
store[`chat${chat.id}`] = chat;
});
result.users.forEach((user) => {
result.users?.forEach((user) => {
store[`user${user.id}`] = user;
});

View File

@ -4,6 +4,7 @@ import React, {
useState, useCallback, memo, useEffect, useMemo,
} from '../../lib/teact/teact';
import { TME_LINK_PREFIX } from '../../config';
import { debounce } from '../../util/schedulers';
import useLang from '../../hooks/useLang';
@ -20,7 +21,6 @@ type OwnProps = {
const MIN_USERNAME_LENGTH = 5;
const MAX_USERNAME_LENGTH = 32;
const LINK_PREFIX = 'https://t.me/';
const LINK_PREFIX_REGEX = /https:\/\/t\.me\/?/i;
const USERNAME_REGEX = /^([a-zA-Z0-9_]+)$/;
@ -79,7 +79,7 @@ const SettingsEditProfile: FC<OwnProps> = ({
const handleUsernameChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
const newUsername = e.target.value.trim().replace(LINK_PREFIX_REGEX, '');
setUsername(newUsername);
e.target.value = `${asLink ? LINK_PREFIX : ''}${newUsername}`;
e.target.value = `${asLink ? TME_LINK_PREFIX : ''}${newUsername}`;
const isValid = isUsernameValid(newUsername);
@ -96,7 +96,7 @@ const SettingsEditProfile: FC<OwnProps> = ({
return (
<InputText
value={`${asLink ? LINK_PREFIX : ''}${username}`}
value={`${asLink ? TME_LINK_PREFIX : ''}${username}`}
onChange={handleUsernameChange}
label={label}
error={usernameError}

View File

@ -15,6 +15,7 @@ import {
FEEDBACK_URL,
IS_BETA,
IS_TEST,
PRODUCTION_HOSTNAME,
} from '../../../config';
import { IS_PWA, IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
import buildClassName from '../../../util/buildClassName';
@ -70,7 +71,6 @@ type StateProps =
}
& Pick<GlobalState, 'connectionState' | 'isSyncing' | 'canInstall'>;
const PRODUCTION_HOSTNAME = 'web.telegram.org';
const LEGACY_VERSION_URL = 'https://web.telegram.org/?legacy=1';
const WEBK_VERSION_URL = 'https://web.telegram.org/k/';

View File

@ -10,6 +10,7 @@ import type { ThemeKey } from '../../types';
import windowSize from '../../util/windowSize';
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
import { TME_LINK_PREFIX } from '../../config';
import { selectCurrentChat, selectTheme, selectUser } from '../../global/selectors';
import buildClassName from '../../util/buildClassName';
import { extractCurrentThemeParams, validateHexColor } from '../../util/themeStyle';
@ -54,7 +55,6 @@ type StateProps = {
const MAIN_BUTTON_ANIMATION_TIME = 250;
const PROLONG_INTERVAL = 45000; // 45s
const ANIMATION_WAIT = 400;
const LINK_PREFIX = 'https://t.me/';
const SANDBOX_ATTRIBUTES = [
'allow-scripts',
'allow-same-origin',
@ -110,7 +110,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
}
if (eventType === 'web_app_open_tg_link') {
const linkUrl = LINK_PREFIX + eventData.path_full;
const linkUrl = TME_LINK_PREFIX + eventData.path_full;
openTelegramLink({ url: linkUrl });
closeWebApp();
}

View File

@ -12,6 +12,7 @@ import PremiumFeatureModal, {
PREMIUM_FEATURE_SECTIONS,
PREMIUM_FEATURE_TITLES,
} from './PremiumFeatureModal';
import { TME_LINK_PREFIX } from '../../../config';
import { formatCurrency } from '../../../util/formatCurrency';
import buildClassName from '../../../util/buildClassName';
import { selectIsCurrentUserPremium, selectUser } from '../../../global/selectors';
@ -77,8 +78,6 @@ type StateProps = {
premiumBotUsername?: string;
};
const LINK_PREFIX = 'https://t.me/';
const PremiumMainModal: FC<OwnProps & StateProps> = ({
isOpen,
fromUser,
@ -127,7 +126,7 @@ const PremiumMainModal: FC<OwnProps & StateProps> = ({
});
} else if (premiumBotUsername) {
openTelegramLink({
url: `${LINK_PREFIX}${premiumBotUsername}?start=${startParam || 'promo'}`,
url: `${TME_LINK_PREFIX}${premiumBotUsername}?start=${startParam || 'promo'}`,
});
closePremiumModal();
}

View File

@ -20,7 +20,7 @@ import {
isActionMessage, isChatChannel,
isChatGroup, isOwnMessage, areReactionsEmpty, isUserId, isMessageLocal, getMessageVideo,
} from '../../../global/helpers';
import { SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
import { SERVICE_NOTIFICATIONS_USER_ID, TME_LINK_PREFIX } from '../../../config';
import { getDayStartAt } from '../../../util/dateFormat';
import buildClassName from '../../../util/buildClassName';
import { REM } from '../../common/helpers/mediaDimensions';
@ -326,7 +326,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
}, [closeMenu, copyMessagesByIds]);
const handleCopyLink = useCallback(() => {
copyTextToClipboard(`https://t.me/${chatUsername || `c/${message.chatId.replace('-', '')}`}/${message.id}`);
copyTextToClipboard(`${TME_LINK_PREFIX}${chatUsername || `c/${message.chatId.replace('-', '')}`}/${message.id}`);
closeMenu();
}, [chatUsername, closeMenu, message]);

View File

@ -1,6 +1,9 @@
import type { FC } from '../../lib/teact/teact';
import React, { memo } from '../../lib/teact/teact';
import React, { memo, useCallback, useEffect } from '../../lib/teact/teact';
import { getActions } from '../../global';
import type { FC } from '../../lib/teact/teact';
import { TME_LINK_PREFIX } from '../../config';
import useLang from '../../hooks/useLang';
import './ConfirmPayment.scss';
@ -9,16 +12,47 @@ export type OwnProps = {
url: string;
};
interface IframeCallbackEvent {
eventType: string;
eventData: {
path_full: string;
};
}
const ConfirmPayment: FC<OwnProps> = ({ url }) => {
const { closePaymentModal, openTelegramLink } = getActions();
const lang = useLang();
const handleMessage = useCallback((event: MessageEvent<string>) => {
try {
const data = JSON.parse(event.data) as IframeCallbackEvent;
const { eventType, eventData } = data;
if (eventType !== 'web_app_open_tg_link') {
return;
}
const linkUrl = TME_LINK_PREFIX + eventData.path_full;
openTelegramLink({ url: linkUrl });
closePaymentModal();
} catch (err) {
// Ignore other messages
}
}, [closePaymentModal, openTelegramLink]);
useEffect(() => {
window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}, [handleMessage]);
return (
<div className="ConfirmPayment">
<iframe
src={url}
title={lang('Checkout.WebConfirmation.Title')}
allow="payment"
sandbox="allow-forms allow-scripts allow-same-origin allow-top-navigation"
sandbox="allow-modals allow-forms allow-scripts allow-same-origin allow-top-navigation"
className="ConfirmPayment__content"
/>
</div>

View File

@ -3,6 +3,8 @@ import type { ApiLimitType } from './global/types';
export const APP_NAME = process.env.APP_NAME || 'Telegram WebZ';
export const APP_VERSION = process.env.APP_VERSION!;
export const PRODUCTION_HOSTNAME = 'web.telegram.org';
export const DEBUG = process.env.APP_ENV !== 'production';
export const DEBUG_MORE = false;
@ -191,6 +193,7 @@ export const RE_MENTION_TEMPLATE = '(@[\\w\\d_-]+)';
export const RE_TG_LINK = /^tg:(\/\/)?([?=&\d\w_-]+)?/gm;
export const RE_TME_LINK = /^(?:https?:\/\/)?(?:t\.me\/)/gm;
export const RE_TELEGRAM_LINK = /^(?:https?:\/\/)?(?:telegram\.org\/)/gm;
export const TME_LINK_PREFIX = 'https://t.me/';
// eslint-disable-next-line max-len
export const COUNTRIES_WITH_12H_TIME_FORMAT = new Set(['AU', 'BD', 'CA', 'CO', 'EG', 'HN', 'IE', 'IN', 'JO', 'MX', 'MY', 'NI', 'NZ', 'PH', 'PK', 'SA', 'SV', 'US']);

View File

@ -1,5 +1,6 @@
import { addActionHandler } from '../../index';
import { IS_PRODUCTION_HOST } from '../../../util/environment';
import { clearPayment } from '../../reducers';
addActionHandler('apiUpdate', (global, actions, update) => {
@ -9,7 +10,13 @@ addActionHandler('apiUpdate', (global, actions, update) => {
if (update.slug && inputInvoice && 'slug' in inputInvoice && inputInvoice.slug !== update.slug) {
return undefined;
}
global = clearPayment(global);
// On the production host, the payment frame receives a message with the payment event,
// after which the payment form closes. In other cases, the payment form must be closed manually.
if (!IS_PRODUCTION_HOST) {
global = clearPayment(global);
}
return {
...global,
payment: {

View File

@ -12,7 +12,7 @@ import {
import type { NotifyException, NotifySettings } from '../../types';
import type { LangFn } from '../../hooks/useLang';
import { ARCHIVED_FOLDER_ID, REPLIES_USER_ID } from '../../config';
import { ARCHIVED_FOLDER_ID, REPLIES_USER_ID, TME_LINK_PREFIX } from '../../config';
import { orderBy } from '../../util/iteratees';
import { getUserFirstOrLastName } from './users';
import { formatDateToString, formatTime } from '../../util/dateFormat';
@ -96,7 +96,7 @@ export function getChatDescription(chat: ApiChat) {
export function getChatLink(chat: ApiChat) {
const { username } = chat;
if (username) {
return `https://t.me/${username}`;
return `${TME_LINK_PREFIX}${username}`;
}
const { inviteLink } = chat.fullInfo || {};

View File

@ -7,6 +7,7 @@ import {
SUPPORTED_VIDEO_CONTENT_TYPES,
VIDEO_MOV_TYPE,
CONTENT_TYPES_WITH_PREVIEW,
PRODUCTION_HOSTNAME,
} from '../config';
export * from './environmentWebp';
@ -35,6 +36,7 @@ export function getPlatform() {
return os;
}
export const IS_PRODUCTION_HOST = window.location.host === PRODUCTION_HOSTNAME;
export const PLATFORM_ENV = getPlatform();
export const IS_MAC_OS = PLATFORM_ENV === 'macOS';
export const IS_IOS = PLATFORM_ENV === 'iOS';