Boost Modal: Support multiple boosts for one channel (#3963)
This commit is contained in:
parent
cd28a97822
commit
62f742c023
@ -212,19 +212,32 @@ export async function fetchMyBoosts() {
|
||||
};
|
||||
}
|
||||
|
||||
export function applyBoost({
|
||||
export async function applyBoost({
|
||||
chat,
|
||||
slots,
|
||||
} : {
|
||||
chat: ApiChat;
|
||||
slots: number[];
|
||||
}) {
|
||||
return invokeRequest(new GramJs.premium.ApplyBoost({
|
||||
const result = await invokeRequest(new GramJs.premium.ApplyBoost({
|
||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||
slots,
|
||||
}), {
|
||||
shouldReturnTrue: true,
|
||||
});
|
||||
}));
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const boosts = result.myBoosts.map(buildApiMyBoost);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
boosts,
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchBoostsStatus({
|
||||
|
||||
@ -5,11 +5,11 @@ export function getBoostProgressInfo(boostInfo: ApiBoostsStatus, freezeOnLevelUp
|
||||
level, boosts, currentLevelBoosts, nextLevelBoosts, hasMyBoost,
|
||||
} = boostInfo;
|
||||
|
||||
const currentLevel = level;
|
||||
const hasNextLevel = Boolean(nextLevelBoosts);
|
||||
|
||||
const isJustUpgraded = freezeOnLevelUp && boosts === currentLevelBoosts && hasMyBoost;
|
||||
|
||||
const currentLevel = isJustUpgraded ? level - 1 : level;
|
||||
const hasNextLevel = Boolean(nextLevelBoosts);
|
||||
|
||||
const levelProgress = (!nextLevelBoosts || isJustUpgraded) ? 1
|
||||
: (boosts - currentLevelBoosts) / (nextLevelBoosts - currentLevelBoosts);
|
||||
const remainingBoosts = nextLevelBoosts ? nextLevelBoosts - boosts : 0;
|
||||
|
||||
@ -33,6 +33,7 @@ type LoadedParams = {
|
||||
progress: number;
|
||||
descriptionText: string;
|
||||
isBoosted?: boolean;
|
||||
canBoostMore?: boolean;
|
||||
};
|
||||
|
||||
type BoostInfo = ({
|
||||
@ -100,6 +101,7 @@ const BoostModal = ({
|
||||
value,
|
||||
progress,
|
||||
descriptionText,
|
||||
canBoostMore,
|
||||
}: BoostInfo = useMemo(() => {
|
||||
if (!info?.boostStatus || !chat) {
|
||||
return {
|
||||
@ -112,7 +114,8 @@ const BoostModal = ({
|
||||
level, currentLevelBoosts, hasMyBoost,
|
||||
} = info.boostStatus;
|
||||
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts);
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, chat.id);
|
||||
const areBoostsInDifferentChannels = info?.myBoosts && !areAllBoostsInChannel(info.myBoosts, chat.id);
|
||||
|
||||
const {
|
||||
boosts,
|
||||
@ -163,10 +166,11 @@ const BoostModal = ({
|
||||
descriptionText: description,
|
||||
boost: firstBoost,
|
||||
isBoosted: hasBoost,
|
||||
canBoostMore: areBoostsInDifferentChannels,
|
||||
};
|
||||
}, [chat, chatTitle, info, lang]);
|
||||
|
||||
const isBoostDisabled = !boost && isCurrentUserPremium;
|
||||
const isBoostDisabled = !info?.myBoosts?.length && isCurrentUserPremium;
|
||||
const isReplacingBoost = boost?.chatId && boost.chatId !== info?.chatId;
|
||||
|
||||
const handleApplyBoost = useLastCallback(() => {
|
||||
@ -187,10 +191,11 @@ const BoostModal = ({
|
||||
openPremiumDialog();
|
||||
}
|
||||
|
||||
closeBoostModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBoosted) {
|
||||
if (!canBoostMore) {
|
||||
closeBoostModal();
|
||||
return;
|
||||
}
|
||||
@ -231,10 +236,10 @@ const BoostModal = ({
|
||||
</div>
|
||||
<div className="dialog-buttons">
|
||||
<Button isText className="confirm-dialog-button" disabled={isBoostDisabled} onClick={handleButtonClick}>
|
||||
{!isBoosted ? (
|
||||
{canBoostMore ? (
|
||||
<>
|
||||
<Icon name="boost" />
|
||||
{lang('ChannelBoost.BoostChannel')}
|
||||
{lang(isBoosted && canBoostMore ? 'BoostingBoostAgain' : 'ChannelBoost.BoostChannel')}
|
||||
</>
|
||||
) : lang('OK')}
|
||||
</Button>
|
||||
@ -316,14 +321,20 @@ const BoostModal = ({
|
||||
);
|
||||
};
|
||||
|
||||
function getFirstAvailableBoost(myBoosts: ApiMyBoost[]) {
|
||||
return myBoosts.find((boost) => !boost.chatId) || myBoosts.sort((a, b) => a.date - b.date)[0];
|
||||
function getFirstAvailableBoost(myBoosts: ApiMyBoost[], chatId?: string) {
|
||||
return myBoosts.find((boost) => !boost.chatId)
|
||||
|| myBoosts.filter((b) => chatId && b.chatId !== chatId)
|
||||
.sort((a, b) => a.date - b.date)[0];
|
||||
}
|
||||
|
||||
function areAllBoostsInChannel(myBoosts: ApiMyBoost[], chatId: string) {
|
||||
return myBoosts.every((boost) => boost.chatId === chatId);
|
||||
}
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { info }): StateProps => {
|
||||
const chat = info && selectChat(global, info?.chatId);
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts);
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, info.chatId);
|
||||
const boostedChat = firstBoost?.chatId ? selectChat(global, firstBoost?.chatId) : undefined;
|
||||
|
||||
return {
|
||||
|
||||
@ -611,6 +611,20 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
let tabState = selectTabState(global, tabId);
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
if (tabState.boostModal) {
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
...tabState.boostModal,
|
||||
myBoosts: result.boosts,
|
||||
},
|
||||
}, tabId);
|
||||
}
|
||||
setGlobal(global);
|
||||
|
||||
const newStatusResult = await callApi('fetchBoostsStatus', {
|
||||
chat,
|
||||
});
|
||||
@ -620,7 +634,7 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
const tabState = selectTabState(global, tabId);
|
||||
tabState = selectTabState(global, tabId);
|
||||
if (!tabState.boostModal?.boostStatus) return;
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user