Deep Link: Support stars_topup links (#5054)
Co-authored-by: Dmitry Kabanov <dmitrykabanovdev@gmail.com> Co-authored-by: Dmitry Kabanov <153344039+dmitrykabanovdev@users.noreply.github.com> Co-authored-by: Alexander Zinchuk <alx.zinchuk@gmail.com>
This commit is contained in:
parent
1dc29627bd
commit
1c25bf1fe5
@ -41,6 +41,7 @@ const TRANSACTION_TABS: TabWithProperties[] = [
|
|||||||
{ title: 'StarsTransactionsOutgoing' },
|
{ title: 'StarsTransactionsOutgoing' },
|
||||||
];
|
];
|
||||||
const TRANSACTION_ITEM_CLASS = 'StarsTransactionItem';
|
const TRANSACTION_ITEM_CLASS = 'StarsTransactionItem';
|
||||||
|
const SUBSCRIPTION_PURPOSE = 'subs';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
modal: TabState['starsBalanceModal'];
|
modal: TabState['starsBalanceModal'];
|
||||||
@ -69,15 +70,19 @@ const StarsBalanceModal = ({
|
|||||||
|
|
||||||
const isOpen = Boolean(modal && starsBalanceState);
|
const isOpen = Boolean(modal && starsBalanceState);
|
||||||
|
|
||||||
const { originStarsPayment, originReaction, originGift } = modal || {};
|
const {
|
||||||
|
originStarsPayment, originReaction, originGift, topup,
|
||||||
|
} = modal || {};
|
||||||
|
|
||||||
|
const shouldOpenOnBuy = originStarsPayment || originReaction || originGift || topup;
|
||||||
|
|
||||||
const ongoingTransactionAmount = originStarsPayment?.form?.invoice?.totalAmount
|
const ongoingTransactionAmount = originStarsPayment?.form?.invoice?.totalAmount
|
||||||
|| originStarsPayment?.subscriptionInfo?.subscriptionPricing?.amount
|
|| originStarsPayment?.subscriptionInfo?.subscriptionPricing?.amount
|
||||||
|| originReaction?.amount
|
|| originReaction?.amount
|
||||||
|| originGift?.gift.stars;
|
|| originGift?.gift.stars
|
||||||
|
|| topup?.balanceNeeded;
|
||||||
const starsNeeded = ongoingTransactionAmount ? ongoingTransactionAmount - (balance || 0) : undefined;
|
const starsNeeded = ongoingTransactionAmount ? ongoingTransactionAmount - (balance || 0) : undefined;
|
||||||
const starsNeededText = useMemo(() => {
|
const starsNeededText = useMemo(() => {
|
||||||
if (!starsNeeded || starsNeeded < 0) return undefined;
|
|
||||||
const global = getGlobal();
|
const global = getGlobal();
|
||||||
|
|
||||||
if (originReaction) {
|
if (originReaction) {
|
||||||
@ -98,11 +103,15 @@ const StarsBalanceModal = ({
|
|||||||
return oldLang('StarsNeededTextGift', getUserFullName(user));
|
return oldLang('StarsNeededTextGift', getUserFullName(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
if (topup?.purpose === SUBSCRIPTION_PURPOSE) {
|
||||||
}, [starsNeeded, originReaction, originStarsPayment, originGift, oldLang]);
|
return oldLang('StarsNeededTextLink');
|
||||||
|
}
|
||||||
|
|
||||||
const shouldShowItems = Boolean(history?.all?.transactions.length && !originStarsPayment && !originReaction);
|
return undefined;
|
||||||
const shouldSuggestGifting = !originStarsPayment && !originReaction;
|
}, [originReaction, originStarsPayment, originGift, topup?.purpose, oldLang]);
|
||||||
|
|
||||||
|
const shouldShowItems = Boolean(history?.all?.transactions.length && !shouldOpenOnBuy);
|
||||||
|
const shouldSuggestGifting = !shouldOpenOnBuy;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
@ -113,13 +122,13 @@ const StarsBalanceModal = ({
|
|||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ongoingTransactionAmount) {
|
if (shouldOpenOnBuy) {
|
||||||
showBuyOptions();
|
showBuyOptions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hideBuyOptions();
|
hideBuyOptions();
|
||||||
}, [ongoingTransactionAmount]);
|
}, [shouldOpenOnBuy]);
|
||||||
|
|
||||||
const tosText = useMemo(() => {
|
const tosText = useMemo(() => {
|
||||||
if (!isOpen) return undefined;
|
if (!isOpen) return undefined;
|
||||||
|
|||||||
@ -40,7 +40,6 @@ export type OwnProps = {
|
|||||||
name?: string;
|
name?: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
shippingMethod?: string;
|
shippingMethod?: string;
|
||||||
botName?: string;
|
|
||||||
};
|
};
|
||||||
totalPrice?: number;
|
totalPrice?: number;
|
||||||
needAddress?: boolean;
|
needAddress?: boolean;
|
||||||
|
|||||||
@ -626,7 +626,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
temporaryPassword,
|
temporaryPassword,
|
||||||
isExtendedMedia,
|
isExtendedMedia,
|
||||||
url,
|
url,
|
||||||
botId,
|
|
||||||
} = selectTabState(global).payment;
|
} = selectTabState(global).payment;
|
||||||
|
|
||||||
const { invoice, nativeParams, nativeProvider } = form || {};
|
const { invoice, nativeParams, nativeProvider } = form || {};
|
||||||
@ -640,7 +639,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const chat = inputInvoice && 'chatId' in inputInvoice ? selectChat(global, inputInvoice.chatId!) : undefined;
|
const chat = inputInvoice && 'chatId' in inputInvoice ? selectChat(global, inputInvoice.chatId!) : undefined;
|
||||||
const isProviderError = Boolean(invoice && (!providerName || !SUPPORTED_PROVIDERS.has(providerName)));
|
const isProviderError = Boolean(invoice && (!providerName || !SUPPORTED_PROVIDERS.has(providerName)));
|
||||||
const { needCardholderName, needCountry, needZip } = (nativeParams || {});
|
const { needCardholderName, needCountry, needZip } = (nativeParams || {});
|
||||||
const bot = botId ? selectUser(global, botId) : undefined;
|
const bot = form?.botId ? selectUser(global, form.botId) : undefined;
|
||||||
const botName = getUserFullName(bot);
|
const botName = getUserFullName(bot);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import type { ActionReturnType } from '../../types';
|
import type { ActionReturnType } from '../../types';
|
||||||
|
|
||||||
import { areDeepEqual } from '../../../util/areDeepEqual';
|
|
||||||
import { formatCurrencyAsString } from '../../../util/formatCurrency';
|
import { formatCurrencyAsString } from '../../../util/formatCurrency';
|
||||||
import * as langProvider from '../../../util/oldLangProvider';
|
import * as langProvider from '../../../util/oldLangProvider';
|
||||||
import { addActionHandler, setGlobal } from '../../index';
|
import { addActionHandler, setGlobal } from '../../index';
|
||||||
@ -17,13 +16,24 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
|||||||
|
|
||||||
const { totalAmount, currency } = invoice;
|
const { totalAmount, currency } = invoice;
|
||||||
|
|
||||||
actions.showNotification({
|
if (paymentState.inputInvoice?.type === 'stars') {
|
||||||
tabId,
|
actions.closeStarsBalanceModal({ tabId });
|
||||||
message: langProvider.oldTranslate('PaymentInfoHint', [
|
actions.showNotification({
|
||||||
formatCurrencyAsString(totalAmount, currency, langProvider.getTranslationFn().code),
|
message: langProvider.oldTranslate('StarsAcquiredInfo', paymentState.inputInvoice.stars),
|
||||||
form.title,
|
title: langProvider.oldTranslate('StarsAcquired'),
|
||||||
]),
|
icon: 'star',
|
||||||
});
|
tabId,
|
||||||
|
});
|
||||||
|
actions.requestConfetti({ withStars: true, tabId });
|
||||||
|
} else {
|
||||||
|
actions.showNotification({
|
||||||
|
tabId,
|
||||||
|
message: langProvider.oldTranslate('PaymentInfoHint', [
|
||||||
|
formatCurrencyAsString(totalAmount, currency, langProvider.getTranslationFn().code),
|
||||||
|
form.title,
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
|
|
||||||
@ -69,8 +79,7 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
|||||||
}
|
}
|
||||||
const starsModalState = selectTabState(global, tabId).starsGiftModal;
|
const starsModalState = selectTabState(global, tabId).starsGiftModal;
|
||||||
|
|
||||||
if (starsModalState && starsModalState.isOpen
|
if (starsModalState?.isOpen && inputInvoice.userId === starsModalState.forUserId) {
|
||||||
&& areDeepEqual(inputInvoice.userId, starsModalState.forUserId)) {
|
|
||||||
global = updateTabState(global, {
|
global = updateTabState(global, {
|
||||||
starsGiftModal: {
|
starsGiftModal: {
|
||||||
...starsModalState,
|
...starsModalState,
|
||||||
@ -78,22 +87,7 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
|||||||
},
|
},
|
||||||
}, tabId);
|
}, tabId);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (inputInvoice?.type === 'stars') {
|
|
||||||
const starsModalState = selectTabState(global, tabId).starsGiftModal;
|
|
||||||
|
|
||||||
if (starsModalState && starsModalState.isOpen) {
|
|
||||||
global = updateTabState(global, {
|
|
||||||
starsGiftModal: {
|
|
||||||
...starsModalState,
|
|
||||||
isCompleted: true,
|
|
||||||
},
|
|
||||||
}, tabId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputInvoice?.type === 'stars' || inputInvoice?.type === 'stargift') {
|
|
||||||
actions.requestConfetti({ withStars: true, tabId });
|
actions.requestConfetti({ withStars: true, tabId });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import type { ApiUserStarGift } from '../../../api/types';
|
|||||||
import type { ActionReturnType } from '../../types';
|
import type { ActionReturnType } from '../../types';
|
||||||
|
|
||||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
|
import * as langProvider from '../../../util/oldLangProvider';
|
||||||
import { getPrizeStarsTransactionFromGiveaway, getStarsTransactionFromGift } from '../../helpers/payments';
|
import { getPrizeStarsTransactionFromGiveaway, getStarsTransactionFromGift } from '../../helpers/payments';
|
||||||
import { addActionHandler } from '../../index';
|
import { addActionHandler } from '../../index';
|
||||||
import {
|
import {
|
||||||
@ -12,7 +13,13 @@ import { selectChatMessage, selectStarsPayment } from '../../selectors';
|
|||||||
|
|
||||||
addActionHandler('processOriginStarsPayment', (global, actions, payload): ActionReturnType => {
|
addActionHandler('processOriginStarsPayment', (global, actions, payload): ActionReturnType => {
|
||||||
const { originData, status, tabId = getCurrentTabId() } = payload;
|
const { originData, status, tabId = getCurrentTabId() } = payload;
|
||||||
const { originStarsPayment, originReaction, originGift } = originData || {};
|
const {
|
||||||
|
originStarsPayment, originReaction, originGift, topup,
|
||||||
|
} = originData || {};
|
||||||
|
|
||||||
|
if (!originStarsPayment && !originReaction && !originGift && !topup) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
actions.closeStarsBalanceModal({ tabId });
|
actions.closeStarsBalanceModal({ tabId });
|
||||||
|
|
||||||
@ -105,9 +112,27 @@ addActionHandler('openStarsBalanceModal', (global, actions, payload): ActionRetu
|
|||||||
originStarsPayment,
|
originStarsPayment,
|
||||||
originReaction,
|
originReaction,
|
||||||
originGift,
|
originGift,
|
||||||
|
topup,
|
||||||
|
shouldIgnoreBalance,
|
||||||
tabId = getCurrentTabId(),
|
tabId = getCurrentTabId(),
|
||||||
} = payload || {};
|
} = payload || {};
|
||||||
|
|
||||||
|
const starBalance = global.stars?.balance;
|
||||||
|
|
||||||
|
if (!shouldIgnoreBalance && starBalance && topup && topup.balanceNeeded <= starBalance) {
|
||||||
|
actions.showNotification({
|
||||||
|
message: langProvider.oldTranslate('StarsTopupLinkEnough'),
|
||||||
|
actionText: langProvider.oldTranslate('StarsTopupLinkTopupAnyway'),
|
||||||
|
action: {
|
||||||
|
action: 'openStarsBalanceModal',
|
||||||
|
payload: { topup, shouldIgnoreBalance: true, tabId },
|
||||||
|
},
|
||||||
|
icon: 'star',
|
||||||
|
tabId,
|
||||||
|
});
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
global = clearStarPayment(global, tabId);
|
global = clearStarPayment(global, tabId);
|
||||||
|
|
||||||
// Always refresh status on opening
|
// Always refresh status on opening
|
||||||
@ -118,6 +143,7 @@ addActionHandler('openStarsBalanceModal', (global, actions, payload): ActionRetu
|
|||||||
originStarsPayment,
|
originStarsPayment,
|
||||||
originReaction,
|
originReaction,
|
||||||
originGift,
|
originGift,
|
||||||
|
topup,
|
||||||
},
|
},
|
||||||
}, tabId);
|
}, tabId);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -875,6 +875,10 @@ export type TabState = {
|
|||||||
messageId: number;
|
messageId: number;
|
||||||
amount: number;
|
amount: number;
|
||||||
};
|
};
|
||||||
|
topup?: {
|
||||||
|
balanceNeeded: number;
|
||||||
|
purpose?: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
giftInfoModal?: {
|
giftInfoModal?: {
|
||||||
@ -2375,6 +2379,11 @@ export interface ActionPayloads {
|
|||||||
messageId: number;
|
messageId: number;
|
||||||
amount: number;
|
amount: number;
|
||||||
};
|
};
|
||||||
|
topup?: {
|
||||||
|
balanceNeeded: number;
|
||||||
|
purpose?: string;
|
||||||
|
};
|
||||||
|
shouldIgnoreBalance?: boolean;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
closeStarsBalanceModal: WithTabId | undefined;
|
closeStarsBalanceModal: WithTabId | undefined;
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { isUsernameValid } from './username';
|
|||||||
|
|
||||||
export type DeepLinkMethod = 'resolve' | 'login' | 'passport' | 'settings' | 'join' | 'addstickers' | 'addemoji' |
|
export type DeepLinkMethod = 'resolve' | 'login' | 'passport' | 'settings' | 'join' | 'addstickers' | 'addemoji' |
|
||||||
'setlanguage' | 'addtheme' | 'confirmphone' | 'socks' | 'proxy' | 'privatepost' | 'bg' | 'share' | 'msg' | 'msg_url' |
|
'setlanguage' | 'addtheme' | 'confirmphone' | 'socks' | 'proxy' | 'privatepost' | 'bg' | 'share' | 'msg' | 'msg_url' |
|
||||||
'invoice' | 'addlist' | 'boost' | 'giftcode' | 'message' | 'premium_offer' | 'premium_multigift';
|
'invoice' | 'addlist' | 'boost' | 'giftcode' | 'message' | 'premium_offer' | 'premium_multigift' | 'stars_topup';
|
||||||
|
|
||||||
interface PublicMessageLink {
|
interface PublicMessageLink {
|
||||||
type: 'publicMessageLink';
|
type: 'publicMessageLink';
|
||||||
|
|||||||
@ -71,6 +71,7 @@ export const processDeepLink = (url: string): boolean => {
|
|||||||
openStoryViewerByUsername,
|
openStoryViewerByUsername,
|
||||||
processBoostParameters,
|
processBoostParameters,
|
||||||
checkGiftCode,
|
checkGiftCode,
|
||||||
|
openStarsBalanceModal,
|
||||||
} = actions;
|
} = actions;
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
@ -176,6 +177,15 @@ export const processDeepLink = (url: string): boolean => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'stars_topup': {
|
||||||
|
const { balance, purpose } = params;
|
||||||
|
const balanceNeeded = Number(balance);
|
||||||
|
if (!balanceNeeded || balanceNeeded < 0) return true;
|
||||||
|
|
||||||
|
openStarsBalanceModal({ topup: { balanceNeeded, purpose } });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'boost': {
|
case 'boost': {
|
||||||
const { channel, domain } = params;
|
const { channel, domain } = params;
|
||||||
const isPrivate = Boolean(channel);
|
const isPrivate = Boolean(channel);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user